Compare commits

..
2595 changed files with 158987 additions and 475248 deletions

No files matched your search

-285
View File
@@ -1,285 +0,0 @@
define dump_bt
set $t = $arg0
while $t
printf "[0x%08x] ", $t
if $t->function_state.function->common.function_name
printf "%s() ", $t->function_state.function->common.function_name
else
printf "??? "
end
if $t->op_array != 0
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
end
set $t = $t->prev_execute_data
printf "\n"
end
end
document dump_bt
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
end
define printzv
set $ind = 0
____printzv $arg0 0
end
document printzv
prints content of zval
end
define ____printzv
set $zvalue = $arg0
if $zvalue->type == 0
set $typename = "NULL"
end
if $zvalue->type == 1
set $typename = "long"
end
if $zvalue->type == 2
set $typename = "double"
end
if $zvalue->type == 3
set $typename = "string"
end
if $zvalue->type == 4
set $typename = "array"
end
if $zvalue->type == 5
set $typename = "object"
end
if $zvalue->type == 6
set $typename = "bool"
end
if $zvalue->type == 7
set $typename = "resource"
end
if $zvalue->type == 8
set $typename = "constant"
end
if $zvalue->type == 9
set $typename = "const_array"
end
printf "[0x%08x] ", $zvalue
if $zvalue == executor_globals.uninitialized_zval_ptr
printf "*uninitialized* "
end
printf "(refcount=%d) %s: ", $zvalue->refcount, $typename
if $zvalue->type == 1
printf "%ld", $zvalue->value.lval
end
if $zvalue->type == 2
printf "%lf", $zvalue->value.dval
end
if $zvalue->type == 3
printf "\"%s\"(%d)", $zvalue->value.str.val, $zvalue->value.str.len
end
if $zvalue->type == 4
if ! $arg1
printf "{\n"
set $ind = $ind + 1
____print_ht $zvalue->value.ht
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
printf "}"
end
end
if $zvalue->type == 5
if ! $arg1
printf "(prop examination disabled due to a gdb bug)"
# set $ht = $zvalue->value.obj.handlers->get_properties($zvalue)
# printf "{\n"
# set $ind = $ind + 1
# ____print_ht $ht
# set $ind = $ind - 1
# set $i = $ind
# while $i > 0
# printf " "
# set $i = $i - 1
# end
# printf "}"
end
end
if $zvalue->type == 6
if $zvalue->lval
printf "true"
else
printf "false"
end
end
if $zvalue->type == 7
printf "#%d", $zvalue->value.lval
end
printf "\n"
end
define ____print_ht
set $ht = $arg0
set $p = $ht->pListHead
while $p != 0
set $zval = *(struct _zval_struct **)$p->pData
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
if $p->nKeyLength > 0
printf "\"%s\" => ", $p->arKey
else
printf "%d => ", $p->h
end
____printzv $zval 1
set $p = $p->pListNext
end
end
define print_ht
set $ind = 1
printf "[0x%08x] {\n", $arg0
____print_ht $arg0
printf "}\n"
end
document print_ht
dumps elements of HashTable made of zval
end
define printzn
set $ind = 0
set $znode = $arg0
if $znode->op_type == 1
set $optype = "IS_CONST"
end
if $znode->op_type == 2
set $optype = "IS_TMP_VAR"
end
if $znode->op_type == 4
set $optype = "IS_VAR"
end
if $znode->op_type == 8
set $optype = "IS_UNUSED"
end
printf "[0x%08x] %s", $znode, $optype
if $znode->op_type == 1
printf ": "
____printzv &$znode->u.constant
end
if $znode->op_type == 2
printf ": "
set $tvar = (union _temp_variable *)((char *)executor_globals.current_execute_data->Ts + $znode->u.var)
____printzv ((union _temp_variable *)$tvar)->tmp_var
end
if $znode->op_type == 4
printf ": "
set $tvar = (union _temp_variable *)((char *)executor_globals.current_execute_data->Ts + $znode->u.var)
____printzv *$tvar->var.ptr_ptr
end
if $znode->op_type == 8
printf "\n"
end
end
document printzn
print type and content of znode.
usage: printzn &opline->op1
end
define printzops
printf "op1 => "
printzn &execute_data->opline.op1
printf "op2 => "
printzn &execute_data->opline.op2
printf "result => "
printzn &execute_data->opline.result
end
document printzops
dump operands of the current opline
end
define zmemcheck
set $p = alloc_globals.head
set $stat = "?"
set $total_size = 0
if $arg0 != 0
set $not_found = 1
else
set $not_found = 0
end
printf " block size status file:line\n"
printf "-------------------------------------------------------------------------------\n"
while $p
set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test)
if $arg0 == 0 || (void *)$aptr == (void *)$arg0
if $p->magic == 0x7312f8dc
set $stat = "OK"
end
if $p->magic == 0x99954317
set $stat = "FREED"
end
if $p->magic == 0xfb8277dc
set $stat = "CACHED"
end
set $filename = strrchr($p->filename, '/')
if !$filename
set $filename = $p->filename
else
set $filename = $filename + 1
end
printf " 0x%08x ", $aptr
if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10
printf "ZVAL?(%-2d) ", $p->size
else
printf "%-9d ", $p->size
end
set $total_size = $total_size + $p->size
printf "%-06s %s:%d", $stat, $filename, $p->lineno
if $p->orig_filename
set $orig_filename = strrchr($p->orig_filename, '/')
if !$orig_filename
set $orig_filename = $p->orig_filename
else
set $orig_filename = $orig_filename + 1
end
printf " <= %s:%d\n", $orig_filename, $p->orig_lineno
else
printf "\n"
end
if $arg0 != 0
set $p = 0
set $not_found = 0
else
set $p = $p->pNext
end
else
set $p = $p->pNext
end
end
if $not_found
printf "no such block that begins at 0x%08x.\n", $aptr
end
if $arg0 == 0
printf "-------------------------------------------------------------------------------\n"
printf " total: %d bytes\n", $total_size
end
end
document zmemcheck
show status of a memory block.
usage: zmemcheck [ptr].
if ptr is 0, all blocks will be listed.
end
+32 -178
View File
@@ -5,16 +5,13 @@ PHP Coding Standards
This file lists several standards that any programmer, adding or changing
code in PHP, should follow. Since this file was added at a very late
stage of the development of PHP v3.0, the code base does not (yet) fully
follow it, but it's going in that general direction. Since we are now
well into the version 4 releases, many sections have been recoded to use
these rules.
follow it, but it's going in that general direction.
This is an initial version - it'll most probably grow as time passes.
Code Implementation
-------------------
[0] Document your code in source files and the manual. [tm]
[1] Functions that are given pointers to resources should not free them
For instance, function int mail(char *to, char *from) should NOT free
@@ -48,144 +45,37 @@ Exceptions:
doing so, should return that new length, so it doesn't have to be
recalculated with strlen() (e.g. php_addslashes())
[5] Use php_error_docref() group of functions to report any errors/warnings
during code execution. Use descriptive error messages, and try to avoid
using identical error strings for different stages of an error. For
example, if in order to obtain a URL you have to parse the URL, connect,
and retreive the text, assuming something can go wrong at each of these
stages, don't report an error "Unable to get URL" on all of them, but
instead, write something like "Unable to parse URL", "Unable to connect
to URL server" and "Unable to fetch URL text", respectively.
It has been silently agreed to prefix every php_error() message with the
name of the current function if applicable:
php_error(E_WHATEVER, "%s(): Desc.", get_active_function_name(TSRMLS_C));
This can be done automatically using php_error_docref(). The first
parameter, docref, is either NULL or the URL of a page describing the
error in detail. In most cases you will pass NULL, to generate the URL
from the name of the function being executed:
php_error_docref(NULL TSRMLS_CC, E_WHATEVER, "Desc.");
If you pass a URL, it can either be a full URL beginning with "http://":
php_error_docref("http://externalsite.tld/page.ext#error"
TSRMLS_CC, E_WHATEVER, "Desc.");
Or the name of a manual page without file extension, but with an optional
target anchor. Or simply the anchor within the manual page of the current
function. When using function names you must replace '_' by '-':
php_error_docref("function.ext-func#error" TSRMLS_CC, E_WHATEVER, "Desc.");
To display one or two important parameters after the function name, use
php_error_docref1() or php_error_docref2(). For example, file functions
should display the name of the file opened:
php_error_docref1("function.fopen" TSRMLS_CC, filename,
E_WHATEVER, "Desc.");
php_error_docref2("function.fopen" TSRMLS_CC, filename, openmode,
E_WHATEVER, "Desc.");
Fixing ("unifying") existing php_error() message is a good thing [tm].
[5] Use php_error() to report any errors/warnings during code execution.
Use descriptive error messages, and try to avoid using identical
error strings for different stages of an error. For example,
if in order to obtain a URL you have to parse the URL, connect,
and retreive the text, assuming something can go wrong at each
of these stages, don't report an error "Unable to get URL"
on all of them, but instead, write something like "Unable
to parse URL", "Unable to connect to URL server" and "Unable
to fetch URL text", respectively.
[6] NEVER USE strncat(). If you're absolutely sure you know what you're doing,
check its man page again, and only then, consider using it, and even then,
try avoiding it.
[7] Use PHP_* macros in the PHP source, and ZEND_* macros in the Zend
part of the source. Although the PHP_* macro's are mostly aliased to the
ZEND_* macros it gives a better understanding on what kind of macro you're
calling.
[8] Use assert(). assert.h is included in php.h if it is available. Not only
does good assertion catch bugs, but it also helps with code readability.
- Do not use assert for error handling. Use assert only for the
condition that must be always true.
- Do not use assignments in assert conditions. If you assign inside an
assert condition, you risk an elusive bug that would be very difficult
to spot in a debug build, due to the side effect of the assignment.
Function calls in assert conditions may also cause this problem, if
they modify one of their arguments or global variables.
[9] When commenting out code using a #if statement, do NOT use 0 only. Instead
use "<cvs username here>_0". For example, #if FOO_0, where FOO is your
cvs user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
[10] Do not define functions that are not available. For instance, if a
library is missing a function, do not define the PHP version of the
function, and do not raise a run-time error about the function not
existing. End users should use function_exists() to test for the
existence of a function
[11] Prefer emalloc(), efree(), estrdup(), etc. to their standard C library
counterparts. These functions implement an internal "safety-net"
mechanism that ensures the deallocation of any unfreed memory at the
end of a request. They also provide useful allocation and overflow
information while running in debug mode.
In almost all cases, memory returned to the engine must be allocated
using emalloc().
The use of malloc() should be limited to cases where a third-party
library may need to control or free the memory, or when the memory in
question needs to survive between multiple requests.
Naming Conventions
------------------
[1] Function names for user-level functions should be enclosed with in
the PHP_FUNCTION() macro. They should be in lowercase, with words
underscore delimited, with care taken to minimize the letter count.
Abbreviations should not be used when they greatly decrease the
readability of the function name itself.
[1] Function names for user functions should be enclosed with in
the PHP_FUNCTION() macro.
Good:
'mcrypt_enc_self_test'
'mysql_list_fields'
Ok:
'mcrypt_module_get_algo_supported_key_sizes'
(could be 'mcrypt_mod_get_algo_sup_key_sizes'?)
'get_html_translation_table'
(could be 'html_get_trans_table'?)
Bad:
'hw_GetObjectByQueryCollObj'
'pg_setclientencoding'
'jf_n_s_i'
[2] If they are part of a "parent set" of functions, that parent should
be included in the user function name, and should be clearly related
to the parent program or function family. This should be in the form
of parent_*.
A family of 'foo' functions, for example:
Good:
'foo_select_bar'
'foo_insert_baz'
'foo_delete_baz'
Bad:
'fooselect_bar'
'fooinsertbaz'
'delete_foo_baz'
[3] Function names used by user functions should be prefixed
[2] Function names used by user functions should be prefixed
with "_php_", and followed by a word or an underscore-delimited list of
words, in lowercase letters, that describes the function. If applicable,
they should be declared 'static'.
[4] Variable names must be meaningful. One letter variable names must be
[3] Variable names must be meaningful. One letter variable names must be
avoided, except for places where the variable has no real meaning or
a trivial meaning (e.g. for (i=0; i<100; i++) ...).
[5] Variable names should be in lowercase. Use underscores to separate
[4] Variable names should be in lowercase; Use underscores to seperate
between words.
@@ -202,34 +92,25 @@ Syntax and indentation
is known to accept C++-style comments in C code.
[2] Use K&R-style. Of course, we can't and don't want to
force anybody to use a style he or she is not used to, but,
force anybody to use a style she's not used to, but
at the very least, when you write code that goes into the core
of PHP or one of its standard modules, please maintain the K&R
style. This applies to just about everything, starting with
indentation and comment styles and up to function declaration
indentation and comment styles and up to function decleration
syntax.
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
[3] Be generous with whitespace and braces. Always prefer:
[3] Be generous with whitespace and braces. Always prefer
if (foo) {
bar;
}
to:
if(foo)bar;
Keep one empty line between the variable declaration section and
bar;
}
to
if(foo)bar;
Keep one empty line between the variable decleration section and
the statements in a block, as well as between logical statement
groups in a block. Maintain at least one empty line between
two functions, preferably two.
[4] When indenting, use the tab character. A tab is expected to represent
four spaces. It is important to maintain consistency in indenture so
that definitions, comments, and control structures line up correctly.
Documentation and Folding Hooks
-------------------------------
@@ -239,7 +120,7 @@ prototype before it along with a brief one-line description of what the
function does. It would look like this:
/* {{{ proto int abs(int number)
Returns the absolute value of the number */
Return the absolute value of the number */
PHP_FUNCTION(abs)
{
...
@@ -247,10 +128,11 @@ PHP_FUNCTION(abs)
/* }}} */
The {{{ symbols are the default folding symbols for the folding mode in
Emacs and vim (set fdm=marker). Folding is very useful when dealing with
large files because you can scroll through the file quickly and just unfold
the function you wish to work on. The }}} at the end of each function marks
the end of the fold, and should be on a separate line.
Emacs. vim will soon have support for folding as well. Folding is very
useful when dealing with large files because you can scroll through the
file quickly and just unfold the function you wish to work on. The }}}
at the end of each function marks the end of the fold, and should be on
a separate line.
The "proto" keyword there is just a helper for the doc/genfuncsummary script
which generates a full function summary. Having this keyword in front of the
@@ -260,35 +142,7 @@ messing up the function summary.
Optional arguments are written like this:
/* {{{ proto object imap_header(int stream_id, int msg_no [, int from_length [, int subject_length [, string default_host]]])
Returns a header object with the defined parameters */
And yes, please keep the prototype on a single line, even if that line
is massive.
And yes, please keep everything on a single line, even if that line is massive.
New and Experimental Functions
-----------------------------------
To reduce the problems normally associated with the first public
implementation of a new set of functions, it has been suggested
that the first implementation include a file labeled 'EXPERIMENTAL'
in the function directory, and that the functions follow the
standard prefixing conventions during their initial implementation.
The file labelled 'EXPERIMENTAL' should include the following
information:
Any authoring information (known bugs, future directions of the module).
Ongoing status notes which may not be appropriate for CVS comments.
Aliases & Legacy Documentation
-----------------------------------
You may also have some deprecated aliases with close to duplicate
names, for example, somedb_select_result and somedb_selectresult. For
documentation purposes, these will only be documented by the most
current name, with the aliases listed in the documentation for
the parent function. For ease of reference, user-functions with
completely different names, that alias to the same function (such as
highlight_file and show_source), will be separately documented. The
proto should still be included, describing which function is aliased.
Backwards compatible functions and names should be maintained as long
as the code can be reasonably be kept as part of the codebase. See
/phpdoc/README for more information on documentation.
+1 -1
View File
@@ -1,2 +1,2 @@
For the list of people who've put work into PHP, please see
For the list of people who've put work into PHP 4.0, please see
http://www.php.net/credits.php
+28803 -34126
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+35 -189
View File
@@ -31,29 +31,15 @@ EXTENSION: aolserver
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: activescript
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
MAINTENANCE: Odd Fixes
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: apache
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: apache2
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: cgi
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: cli
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: fhttpd
MAINTENANCE: Unknown
STATUS: Unknown
@@ -63,9 +49,8 @@ MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: nsapi
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
MAINTENANCE: Maintained
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: phttpd
MAINTENANCE: Unknown
@@ -88,18 +73,13 @@ EXTENSION: thttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: webjames
PRIMARY MAINTAINER: Alex Waugh <alex@alexwaugh.com>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
== Database extensions ==
-------------------------------------------------------------------------------
EXTENSION: dba
PRIMARY MAINTAINER: Marcus Börger <helly@php.net>
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -108,13 +88,6 @@ PRIMARY MAINTAINER: Jim Winstead <jimw@php.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: dbx
PRIMARY MAINTAINER: Marc Boeren <M.Boeren@guidance.nl>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.6
COMMENT: DB abstraction for odbc, mysql, pgsql, mssql, fbsql and more, see documentation
-------------------------------------------------------------------------------
EXTENSION: filepro
MAINTENANCE: Unknown
STATUS: Unknown
@@ -136,7 +109,7 @@ STATUS: Experimental
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: interbase
PRIMARY MAINTAINER: Jouni Ahto <jouni.ahto@exdec.fi>, Ard Biesheuvel <ard@ard.nu>
PRIMARY MAINTAINER: Jouni Ahto <jah@mork.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
@@ -144,12 +117,6 @@ EXTENSION: msql
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: msession
PRIMARY MAINTAINER Mark L. Woodward mlwmohawk@mohawksoft.com
MAINTENANCE: Maintained
STATUS: Working/Experimental
COMMENT: Tested on Linux, should work on other UNIX platforms. Backend server code can compile under Windows.
-------------------------------------------------------------------------------
EXTENSION: mssql
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
MAINTENANCE: Maintained
@@ -157,15 +124,13 @@ STATUS: Working
COMMENT: Tested on phpts and isapi versions
-------------------------------------------------------------------------------
EXTENSION: mysql
PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>
MAINTENANCE: Maintained
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: pgsql
PRIMARY MAINTAINER: Yasuo Ohgaki <yohgaki@php.net>
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Jouni Ahto <jah@mork.net>
MAINTENANCE: Odd fixes
STATUS: Working
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
-------------------------------------------------------------------------------
EXTENSION: sybase
MAINTENANCE: Unknown
@@ -176,18 +141,19 @@ MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: oci8
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: odbc
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
PRIMARY MAINTAINER: Andreas Karajannis <Karajannis@gmd.de>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Working
COMMENT: Working except for persistent connections
-------------------------------------------------------------------------------
EXTENSION: oracle
MAINTENANCE: Orphaned
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
MAINTENANCE: Maintained
STATUS: Working
COMMENT: Using the new OCI8 driver is encouraged where possible.
-------------------------------------------------------------------------------
@@ -205,53 +171,23 @@ EXTENSION: bcmath
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: bz2
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: dio
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
EXTENSION: cyrus
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
EXTENSION: calendar
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: com
PRIMARY MAINTAINER: Harald Radi <h.radi@nme.at>
MAINTENANCE: Maintained
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: cpdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: crack
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
EXTENSION: ctype
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: curl
EXTENSION: CURL
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Maintained
STATUS: Working
STATUS: Experimental
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: cybercash
@@ -270,25 +206,18 @@ MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: exif
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.2
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.1
-------------------------------------------------------------------------------
EXTENSION: fdf
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
MAINTENANCE: Maintained
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: fribidi
PRIMARY MAINTAINER: Tal Peer <tal@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: ftp
PRIMARY MAINTAINER: Stefan Esser (sesser@php.net)
MAINTENANCE: Maintained
STATUS: Working
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: gd
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
@@ -299,20 +228,10 @@ EXTENSION: gettext
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: gmp
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: icap
MAINTENANCE: Unknown
STATUS: Obsolete
-------------------------------------------------------------------------------
EXTENSION: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: imap
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
MAINTENANCE: Odd Fixes
@@ -324,13 +243,8 @@ MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: ldap
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mbstring
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
MAINTENANCE: Maintained
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mcal
@@ -339,7 +253,7 @@ MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: mcrypt
PRIMARY MAINTAINER: Derick Rethans <derick@derickrethans.nl>
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -348,26 +262,8 @@ PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: muscat
PRIMARY MAINTAINER: Sam Liddicott <sam@ananova.com>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.5
COMMENT: Not tested against windows, only core API completed, rest under development
-------------------------------------------------------------------------------
EXTENSION: openssl
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: overload
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: pcre
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
PRIMARY MAINTAINER: Andrei Zmievski <andrei@ispi.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -387,24 +283,12 @@ PRIMARY MAINTAINER: Kristian K
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: printer
PRIMARY MAINTAINER: Daniel Beulshausen <daniel@php4win.de>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 4.0.4
COMMENT: Only for Win32
-------------------------------------------------------------------------------
EXTENSION: pspell
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com>
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: qtdom
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.4
-------------------------------------------------------------------------------
EXTENSION: readline
MAINTENANCE: Unknown
STATUS: Unknown
@@ -414,29 +298,11 @@ PRIMARY MAINTAINER: Kristian K
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sablot
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Obsolete
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: satellite
PRIMARY MAINTAINER: David Eriksson <eriksson@php.net>
MAINTENANCE: Odd Fixes
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: session
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: shmop
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: snmp
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Odd Fixes
@@ -444,15 +310,14 @@ STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: sockets
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org>
MAINTENANCE: Maintained
STATUS: Experimental
MAINTENANCE: Unknown
STATUS: Unknown
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: swf
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Deprecated (Use the ming swf extension instead)
COMMENT: Only for Unix (won't change)
MAINTENANCE: Maintained
STATUS: Unix (won't change)
-------------------------------------------------------------------------------
EXTENSION: sysvsem
MAINTENANCE: Unknown
@@ -462,25 +327,15 @@ EXTENSION: sysvshm
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: vpopmail
MAINTENANCE: Unknown
STATUS: Experimental
SINCE: 4.0.5
-------------------------------------------------------------------------------
EXTENSION: wddx
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
PRIMARY MAINTAINER: Andrei Zmievski <andrei@ispi.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xml
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: xslt
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working (mostly)
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: yaz
PRIMARY MAINTAINER: Adam Dickmeiss <adam@indexdata.dk>
@@ -488,19 +343,10 @@ MAINTENANCE: Maintained
STATUS: Unknown
SINCE: 4.0.1
-------------------------------------------------------------------------------
EXTENSION: yp
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: zlib
PRIMARY MAINTAINER: Stefan Roehrich <sr@linux.de>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: zziplib
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.5
-------------------------------------------------------------------------------
# iptc?
+538
View File
@@ -0,0 +1,538 @@
Functions:
Functions marked with 'u' do not work, or may not work correctly under windows.
basic_functions
include
_include
isset
intval
doubleval
strval
short_tags
sleep
u usleep
ksort
asort
sort
count
chr
ord
flush
end
prev
next
reset
current
key
gettype
settype
min
max
addslashes
chop
pos
fsockopen
getimagesize
htmlspecialchars
md5
parse_url
parse_str
phpinfo
phpversion
strlen
strtok
strtoupper
strtolower
strchr
basename
dirname
stripslashes
strstr
strrchr
substr
quotemeta
urlencode
urldecode
ucfirst
strtr
sprintf
printf
exec
system
escapeshellcmd
passthru
soundex
rand
srand
getrandmax
gethostbyaddr
gethostbyname
explode
implode
error_reporting
clearstatcache
get_current_user
getmyuid
getmypid
u getmyinode
getlastmod
base64_decode
base64_encode
abs
ceil
floor
sin
cos
tan
asin
acos
atan
pi
pow
exp
log
log10
sqrt
bindec
hexdec
octdec
decbin
decoct
dechex
getenv
putenv
time
mktime
date
gmdate
getdate
checkdate
microtime
uniqid
u linkinfo
u readlink
u symlink
u link
u unlink
bcmath_functions
bcadd
bcsub
bcmul
bcdiv
bcmod
bcpow
bcsqrt
bcscale
bccomp
dir_functions
opendir
closedir
chdir
rewinddir
readdir
dir
dl_functions
dl(string module_name); dynamicly load a module
dns_functions
gethostbyaddr
gethostbyname
file_functions
pclose
popen
readfile
rewind
rmdir
umask
fclose
feof
fgets
fgetss
fopen
fpassthru
fseek
ftell
fputs
mkdir
rename
copy
tempnam
file
filestat_functions
fileatime
filectime
u filegroup
u fileinode
filemtime
u fileowner
fileperms
filesize
filetype
stat
u chown
u chgrp
u chmod
touch
file_exists
is_executable
is_dir
is_readable
is_writeable
u is_link
header_functions
setcookie
header
mail_functions
mail
reg_functions
ereg
ereg_replace
eregi
eregi_replace
split
sql_regcase
syslog_functions (writes to event log on win NT)
openlog
syslog
closelog
The following are optional modules and may or may not be compiled into php, or may be compiled as a loadable module.
odbc_functions (obsolete, use uodbc below)
sqlconnect
sqldisconnect
sqlfetch
sqlexecdirect
sqlgetdata
sqlfree
sqlrowcount
uodbc_functions
(int) odbc_autocommit($connection_id, $OnOff)
(void) odbc_close($connection_id)
(void) odbc_close_all(void)
(int) odbc_commit($connection_id)
(int) odbc_connect($dsn, $user, $password)
(int) odbc_pconnect($dsn, $user, $password)
(string) odbc_cursor($result_id)
(int) odbc_do($connection_id, $query_string)
(int) odbc_exec($connection_id, $query_string)
(int) odbc_prepare($connection_id, $query_string)
(int) odbc_execute($result_id, $array)
(int) odbc_fetch_row($result_id, $row_number)
(int) odbc_fetch_into($result_id, $row_number, $array_ptr)
(int) odbc_field_len($result_id, $field_number)
(string) odbc_field_name($result_id, $field_number)
(string) odbc_field_type($result_id, $field)
(int) odbc_free_result($result_id)
(int) odbc_num_fields($result_id)
(int) odbc_num_rows($result_id)
(string) odbc_result($result_id, $field)
(int) odbc_result_all($result_id, $format)
(int) odbc_rollback($connection_id)
msql_functions
msql_connect
msql_pconnect
msql_close
msql_select_db
msql_create_db
msql_drop_db
msql_query
msql
msql_list_dbs
msql_list_tables
msql_list_fields
msql_result
msql_num_rows
msql_num_fields
msql_fetch_row
msql_fetch_array
msql_fetch_object
msql_data_seek
msql_fetch_field
msql_field_seek
msql_free_result
msql_fieldname
msql_fieldtable
msql_fieldlen
msql_fieldtype
msql_fieldflags
msql_regcase
/* for downwards compatability */
msql_selectdb
msql_createdb
msql_dropdb
msql_freeresult
msql_numfields
msql_numrows
msql_listdbs
msql_listtables
msql_listfields
msql_dbname
msql_tablename
ldap_functions
ldap_connect
ldap_bind
ldap_unbind
ldap_read
ldap_list
ldap_search
ldap_free_result
ldap_count_entries
ldap_first_entry
ldap_next_entry
ldap_get_entries
ldap_free_entry
ldap_first_attribute
ldap_next_attribute
ldap_get_attributes
ldap_get_values
ldap_get_dn
ldap_dn2ufn
ldap_add
ldap_delete
ldap_modify
gd_functions
imagearc
imagechar
imagecharup
imagecolorallocate
imagecolorclosest
imagecolorexact
imagecolortransparent
imagecopyresized
imagecreate
imagecreatefromgif
imagedestroy
imagefill
imagefilledpolygon
imagefilledrectangle
imagefilltoborder
imagegif
imageinterlace
imageline
imagepolygon
imagerectangle
imagesetpixel
imagestring
imagestringup
imagesx
imagesy
filepro_functions
filepro
filepro_rowcount
filepro_fieldname
filepro_fieldtype
filepro_fieldwidth
filepro_fieldcount
filepro_retrieve
dbm_functions
dblist
dbmopen
dbmclose
dbminsert
dbmfetch
dbmreplace
dbmexists
dbmdelete
dbmfirstkey
dbmnextkey
dbase_functions
dbase_open
dbase_create
dbase_close
dbase_numrecords
dbase_numfields
dbase_add_record
dbase_get_record
dbase_delete_record
dbase_pack
calendar_functions
jdtogregorian
gregoriantojd
jdtojulian
juliantojd
jdtojewish
jewishtojd
jdtofrench
frenchtojd
jddayofweek
jdmonthname
adabas_functions
(int) ada_afetch($result_id, $rownumber, $result array)
(int) ada_autocommit($connection_id, $OnOff)
(void) ada_close($connection_id)
ada_closeall
(int) ada_commit($connection_id)
(int) ada_connect($dsn, $user, $password)
(int) ada_exec($connection_id, $query_string)
(int) ada_fetchrow($result_id, $row?number)
ada_fieldlen
(string) ada_fieldname($result_id, $field_number)
(string) ada_fieldtype($result_id, $field)
(int) ada_freeresult($result_id)
(int) ada_numfields($result_id)
(int) ada_numrows($result_id)
(string) ada_result($result_id, $field)
(int) ada_resultall($result_id, $format)
(int) ada_rollback($connection_id)
***(int) ada_fieldnum($result_id, $field_name) (this function is not in adabase.c
crypt_functions
crypt
mysql_functions
mysql_connect
mysql_pconnect
mysql_close
mysql_select_db
mysql_create_db
mysql_drop_db
mysql_query
mysql
mysql_list_dbs
mysql_list_tables
mysql_list_fields
mysql_affected_rows
mysql_insert_id
mysql_result
mysql_num_rows
mysql_num_fields
mysql_fetch_row
mysql_fetch_array
mysql_fetch_object
mysql_data_seek
mysql_fetch_lengths
mysql_fetch_field
mysql_field_seek
mysql_free_result
mysql_fieldname
mysql_fieldtable
mysql_fieldlen
mysql_fieldtype
mysql_fieldflags
/* for downwards compatability */
mysql_selectdb
mysql_createdb
mysql_dropdb
mysql_freeresult
mysql_numfields
mysql_numrows
mysql_listdbs
mysql_listtables
mysql_listfields
mysql_dbname
mysql_tablename
oracle_functions
ora_close
ora_commit
ora_commitoff
ora_commiton
ora_error
ora_errorcode
ora_exec
ora_fetch
ora_getcolumn
ora_logoff
ora_logon
ora_open
ora_parse
ora_rollback
pgsql_functions
pg_connect
pg_pconnect
pg_close
pg_dbname
pg_errormessage
pg_options
pg_port
pg_tty
pg_host
pg_exec
pg_numrows
pg_numfields
pg_fieldname
pg_fieldsize
pg_fieldtype
pg_fieldnum
pg_result
pg_fieldprtlen
pg_getlastoid
pg_freeresult
pg_locreate
pg_lounlink
pg_loopen
pg_loclose
pg_loread
pg_lowrite
pg_loreadall
sybase_functions
sybase_connect
sybase_pconnect
sybase_close
sybase_select_db
sybase_query
sybase_free_result
sybase_get_last_message
sybase_num_rows
sybase_num_fields
sybase_fetch_row
sybase_fetch_array
sybase_fetch_object
sybase_data_seek
sybase_fetch_field
sybase_field_seek
sybase_result
sybase_old_functions
sybsql_seek
sybsql_exit
sybsql_dbuse
sybsql_query
sybsql_isrow
sybsql_result
sybsql_connect
sybsql_nextrow
sybsql_numrows
sybsql_getfield
sybsql_numfields
sybsql_fieldname
sybsql_result_all
sybsql_checkconnect
+364 -1300
View File
File diff suppressed because it is too large. Load diff
+32 -25
View File
@@ -1,6 +1,6 @@
--------------------------------------------------------------------
The PHP License, version 3.0
Copyright (c) 1999 - 2002 The PHP Group. All rights reserved.
The PHP License, version 2.02
Copyright (c) 1999, 2000 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -8,38 +8,48 @@ modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.
4. Products derived from this software may not be called "PHP", nor
may "PHP" appear in their name, without prior written permission
from group@php.net. You may indicate that your software works in
conjunction with PHP by saying "Foo for PHP" instead of calling
it "PHP Foo" or "phpfoo"
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior permission from the
PHP Group. This does not apply to add-on libraries or tools
that work in conjunction with PHP. In such a case the PHP
name may be used to indicate that the product supports PHP.
5. The PHP Group may publish revised and/or new versions of the
4. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the terms
of that version. You may also choose to use such covered code
under the terms of any subsequent version of the license
of the license, you may always continue to use it under the
terms of that version. You may also choose to use such covered
code under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
6. Redistributions of any form whatsoever must retain the following
5. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP, freely available from
<http://www.php.net/>".
http://www.php.net/".
6. The software incorporates the Zend Engine, a product of Zend
Technologies, Ltd. ("Zend"). The Zend Engine is licensed to the
PHP Association (pursuant to a grant from Zend that can be
found at http://www.php.net/license/ZendGrant/) for
distribution to you under this license agreement, only as a
part of PHP. In the event that you separate the Zend Engine
(or any portion thereof) from the rest of the software, or
modify the Zend Engine, or any portion thereof, your use of the
separated or modified Zend Engine software shall not be governed
by this license, and instead shall be governed by the license
set forth at http://www.zend.com/license/ZendLicense/.
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
@@ -63,6 +73,3 @@ The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see <http://www.php.net>.
This product includes the Zend Engine, freely available at
<http://www.zend.com>.
-23
View File
@@ -1,23 +0,0 @@
#
# Zend
#
$(builddir)/zend_language_scanner.lo: $(builddir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(builddir)/zend_ini_parser.h
$(builddir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
$(builddir)/zend_language_parser.h: $(builddir)/zend_language_parser.c
$(builddir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
$(builddir)/zend_ini_parser.h: $(builddir)/zend_ini_parser.c
$(builddir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
$(builddir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(builddir)/zend_language_parser.h
-78
View File
@@ -1,78 +0,0 @@
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
INSTALL = $(top_srcdir)/build/shtool install -c
INSTALL_DATA = $(INSTALL) -m 644
DEFS = -DPHP_ATOM_INC -I$(top_builddir)/include -I$(top_builddir)/main -I$(top_srcdir)
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
all: $(all_targets)
@echo
@echo "Build complete."
@echo "(It is safe to ignore warnings about tempnam and tmpnam)."
@echo
build-modules: $(PHP_MODULES)
libphp4.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --mode=install cp libphp4.la $(phptempdir)/libphp4.la >/dev/null 2>&1
libs/libphp4.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp4.so
install: $(all_targets) $(install_targets)
install-sapi: $(OVERALL_TARGET)
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
-@if test ! -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
if test -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); \
break; \
fi; \
done; \
fi
@$(INSTALL_IT)
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR)
@echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/"
@rm -f modules/*.la >/dev/null 2>&1
@$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR)
install-tester:
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
@$(mkinstalldirs) $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
install-su: install-pear install-tester
test:
-@if test -x $(SAPI_CLI_PATH) && test ! -z $(SAPI_CLI_PATH); then \
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' $(top_srcdir)/run-tests.php $(TESTS); \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
clean:
find . -name \*.lo | xargs rm -f
find . -name \*.o | xargs rm -f
find . -name \*.la | xargs rm -f
find . -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp4.la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
distclean: clean
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php4.spec sapi/apache/libphp4.module buildmk.stamp
egrep define'.*include/php' configure|sed 's/.*>//'|xargs rm -f
find . -name Makefile | xargs rm -f
.PHONY: all clean install distclean test
.NOEXPORT:
+56
View File
@@ -0,0 +1,56 @@
ZEND_DIR = $(srcdir)/Zend
SUBDIRS = Zend main ext sapi $(TSRM_DIR) $(REGEX_DIR) . $(PEAR_DIR)
LTLIBRARY_NAME = libphp4.la
LTLIBRARY_SOURCES = stub.c
LTLIBRARY_DEPENDENCIES = \
Zend/libZend.la \
sapi/$(PHP_SAPI)/libsapi.la \
main/libmain.la \
$(REGEX_LIB) \
$(EXT_LTLIBS) \
$(TSRM_LIB)
LTLIBRARY_LDFLAGS = -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS)
LTLIBRARY_LIBADD = $(LTLIBRARY_DEPENDENCIES) $(EXTRA_LIBS)
PROGRAM_NAME = php
PROGRAM_SOURCES = stub.c
PROGRAM_LDADD = libphp4.la
PROGRAM_LDFLAGS = -export-dynamic
PROGRAM_DEPENDENCIES = $(PROGRAM_LDADD)
targets = $(LTLIBRARY_NAME) $(PHP_PROGRAM)
install_targets = install-sapi install-modules
include $(top_srcdir)/build/rules.mk
include $(top_srcdir)/build/library.mk
include $(top_srcdir)/build/program.mk
install-sapi:
@$(LIBTOOL) --silent --mode=install cp libphp4.la $(phptempdir)/libphp4.la >/dev/null 2>&1
-@$(mkinstalldirs) $(bindir)
-@if test ! -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
if test -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); \
break; \
fi; \
done; \
fi
$(INSTALL_IT)
install-modules:
@test -d modules && \
$(mkinstalldirs) $(moduledir) && \
echo "installing shared modules into $(moduledir)" && \
rm -f modules/*.la && \
cp modules/* $(moduledir) >/dev/null 2>&1 || true
install-su: install-modules
(cd pear && $(MAKE) install)
.NOEXPORT:
+3 -2342
View File
File diff suppressed because it is too large. Load diff
+17
View File
@@ -0,0 +1,17 @@
How to install PHP with the BCMath arbitrary precision math library?
--------------------------------------------------------------------
Due to license restrictions, the BC math library can no longer be distributed
along with PHP. The BC math library is distributed under the restrictive
GNU Public License, and PHP is no longer distributed under that license, but
under a less restrictive license, the PHP License.
If you want to enable BC math support (recommended), all you have to do is
simply download http://www.php.net/extra/number4.tar.gz, and untar it on the
top level php4 directory.
A typical way of doing this would be (assuming that you have lynx):
cd ~/php4
lynx -dump -source http://www.php.net/extra/number4.tar.gz | gzip -d | tar xvf -
The PHP Group
+17 -20
View File
@@ -1,7 +1,6 @@
This is the first file you should be reading after you get your CVS account.
We'll assume you're basically familiar with CVS, but feel free to post
your questions on the mailing list. Please have a look at
http://cvsbook.red-bean.com/ for more detailed information on CVS.
your questions on the mailing list.
PHP is developed through the efforts of a large number of people.
Collaboration is a Good Thing(tm), and CVS lets us do this. Thus, following
@@ -37,11 +36,8 @@ The next few rules are more of a technical nature.
messages every day. Woe be to those who attempt to mess with it.
2. All news updates intended for public viewing, such as new features,
bug fixes, improvements, etc., should go into the NEWS file.
NB! Lines, starting with @ will go automagically into NEWS file, but
this is NOT recommended, though. Please, add news entries directly to
NEWS file and don't forget to keep them adjusted and sorted.
bug fixes, improvements, etc., should go into the NEWS file. Also see
the note below about automatically updating NEWS in your commit message.
3. Do not commit multiple file and dump all messages in one commit. If you
modified several unrelated files, commit each group separately and
@@ -62,10 +58,13 @@ The next few rules are more of a technical nature.
The format of the commit messages is pretty simple.
If a line begins with #, it is taken to be a comment and will not appear
in the ChangeLog. Everything else goes into the ChangeLog.
in the ChangeLog. If the line begins with @, it will be redirected to the
NEWS file. Everything else goes into the ChangeLog.
It is important to note that if your comment or news logline spans multiple
lines, you have to put # at the beginning of _every_ such line.
lines, you have to put # or @ at the beginning of _every_ such line. Every
entry in NEWS has to have a name after it, so if you did it with someone's
help, put both your names there.
Example. Say you modified two files, datetime.c and string.c. In datetime.c
you added a new format option for date() function, and in string.c you fixed
@@ -77,24 +76,22 @@ For datetime.c:
(PHP date) Added new 'K' format modifier for printing out number of
days until New Year's Eve.
@- Added new 'K' format modifier that will output the number of days
@ until New Year's Eve. (Bob)
For string.c:
(php_trim) Fixed a memory leak resulting from improper use of zval_dtor().
# Man, that thing was leaking all over the place!
@- Memory leak in trim() function has finally been fixed. (Bob)
The # lines will be omitted from the ChangeLog automagically.
The lines above marked with @ will go into NEWS file automagically, and the
# lines will be omitted from the ChangeLog. Alternatively, you might want
to modify NEWS file directly and not use the @ lines.
If you fix some bugs, you should note the bug ID numbers in your
commit message. Bug ID should be prefixed by "#" for easier access to
bug report when developers are browsing CVS via. LXR or Bonsai.
Example:
Fixed pgsql notice handler double free crash bug. Bug #14016
If you don't see your messages in ChangeLog right away, don't worry!
If you don't see your messages in ChangeLog and NEWS right away, don't worry!
These files are updated once a day, so your stuff will not show up until
somewhat later.
somewhat later. Don't go adding stuff to NEWS by hand if you already put @
lines in the commit message.
You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/)
to look at PHP CVS repository in various ways.
-39
View File
@@ -1,39 +0,0 @@
Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
that broke both source and binary compatibility. If you are
maintaining a third party extension, here's how to update it:
If this was your old module entry:
zend_module_entry foo_module_entry = {
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
STANDARD_MODULE_PROPERTIES
};
Here's how it should look if you want your code to build with PHP
4.1.0 and up:
zend_module_entry foo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
#if ZEND_MODULE_API_NO >= 20010901
FOO_VERSION, /* extension version number (string) */
#endif
STANDARD_MODULE_PROPERTIES
};
If you don't care about source compatibility with earlier PHP releases
than 4.1.0, you can drop the #if/#endif lines.
+15 -23
View File
@@ -7,22 +7,17 @@ WHAT IT IS
HOW TO USE IT
Very simple. First, change to the ext/ directory of the PHP 4 sources. If
you just need the basic framework and will be writing all the code in your
functions yourself, you can now do
Very simple. First, cd do directory ext/ in PHP 4 sources. If you just need
the basic framework and will be writing all the code in your functions
yourself, you can now do
./ext_skel --extname=module_name
and everything you need is placed in directory module_name.
[ Note that GNU awk is likely required for this script to work. Debian
systems seem to default to using mawk, so you may need to change the
#! line in skeleton/create_stubs to use gawk explicitly. ]
If you don't need to test the existence of any external header files,
libraries or functions in them, the module is already almost ready to be
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
change back up to PHP sources top directory, and do
and everything you need is placed in directory module_name. In fact, if you
don't need to test the existence of any external header files, libraries or
functions in them, the module is already almost ready to be compiled in PHP.
Just remove 3 comments in your_module_name/config.m4, cd back up to PHP
sources top directory, and do
./buildconf; ./configure --enable-module_name; make
@@ -38,7 +33,7 @@ HOW TO USE IT
FORMAT OF FUNCTION DEFINITIONS FILE
All the definitions must be on one line. In it's simplest form, it's just
the function name, e.g.
the function name, ie.
my_function
@@ -56,13 +51,9 @@ FORMAT OF FUNCTION DEFINITIONS FILE
']'s as there where '['s. Currently, it does not harm if you forget to do it
or there is a wrong amount of ']'s, but this may change in the future.
An additional short description may be added after the parameters.
If present it will be filled into the 'proto' header comments in the stubs
code and the <refpurpose> tag in the XML documentation.
An example:
my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st
my_function(int arg1, int arg2 [, int arg3 [, int arg4]])
Arguments arg3 and arg4 are optional.
@@ -133,8 +124,8 @@ CURRENT LIMITATIONS, BUGS AND OTHER ODDITIES
It can't handle correctly, and probably never will, variable list of
of arguments. (void foo(int bar [, ...])
Don't trust the generated code too much. It tries to be useful in most of
the situations you might encounter, but automatic code generation will never
Don't trust too much the generated code. It tries to be useful in most of
the situations you might encounter, but automatic code generating will never
beat a programmer who knows the real situation at hand. ext_skel is generally
best suited for quickly generating a wrapper for c-library functions you
might want to have available in PHP too.
@@ -159,14 +150,15 @@ PHP_FUNCTION(my_drawtext)
int argc;
int image_id = -1;
int font_id = -1;
???LS_FETCH();
argc = ZEND_NUM_ARGS();
if (argc < 5 || argc > 6 || zend_get_parameters_ex(argc, &image, &text, &font, &x, &y, &color) == FAILURE) {
WRONG_PARAM_COUNT;
}
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???_rsrc_id);
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id);
ZEND_FETCH_RESOURCE(???, ???, image, image_id, "???", ???G());
ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???G());
switch (argc) {
case 6:
-127
View File
@@ -1,127 +0,0 @@
New parameter parsing functions
===============================
It should be easier to parse input parameters to an extension function.
Hence, borrowing from Python's example, there are now a set of functions
that given the string of type specifiers, can parse the input parameters
and store the results in the user specified variables. This avoids most
of the IS_* checks and convert_to_* conversions. The functions also
check for the appropriate number of parameters, and try to output
meaningful error messages.
Prototypes
----------
/* Implemented. */
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
The zend_parse_parameters() function takes the number of parameters
passed to the extension function, the type specifier string, and the
list of pointers to variables to store the results in. The _ex() version
also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
be used as 'flags' to specify that the function should operate quietly
and not output any error messages.
Both functions return SUCCESS or FAILURE depending on the result.
The auto-conversions are performed as necessary. Arrays, objects, and
resources cannot be auto-converted.
Type specifiers
---------------
l - long
d - double
s - string (with possible null bytes) and its length
b - boolean, stored in zend_bool
r - resource (stored in zval)
a - array
o - object (of any type)
O - object (of specific type, specified by class entry)
z - the actual zval
The following characters also have a meaning in the specifier string:
| - indicates that the remaining parameters are optional, they
should be initialized to default values by the extension since they
will not be touched by the parsing function if they are not
passed to it.
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
! - the parameter it follows can be of specified type or NULL (only applies
to 'a', 'o', 'O', 'r', and 'z'). If NULL is passed, the results
pointer is set to NULL as well.
Examples
--------
/* Gets a long, a string and its length, and a zval */
long l;
char *s;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
&l, &s, &s_len, &param) == FAILURE) {
return;
}
/* Gets an object of class specified by my_ce, and an optional double. */
zval *obj;
double d = 0.5;
zend_class_entry my_ce;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
}
/* Gets an object or null, and an array.
If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
&obj, &arr) == FAILURE) {
return;
}
/* Gets a separated array which can also be null. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
&arr) == FAILURE) {
return;
}
/* Get only the first three parameters (useful for varargs functions). */
zval *z;
zend_bool b;
zval *r;
if (zend_parse_parameters(3 TSRMLS_CC, "zbr!",
&z, &b, &r) == FAILURE) {
return;
}
/* Get either a set of 3 longs or a string. */
long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a integer in this case, not a long
* or any other type. If you specify a type which is larger
* than a 'int', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
int length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lll", &l1, &l2, &l3) == SUCCESS) {
/* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"s", &s, &length) == SUCCESS) {
/* manipulate string */
} else {
/* output error */
return;
}
+33 -14
View File
@@ -4,9 +4,10 @@ $Id$
HOW TO CREATE A SELF-CONTAINED PHP EXTENSION
A self-contained extension can be distributed independently of
the PHP source. To create such an extension, two things are
the PHP source. To create such an extension, three things are
required:
- Makefile template (Makefile.in)
- Configuration file (config.m4)
- Source code for your module
@@ -73,9 +74,28 @@ DEFINING THE NEW EXTENSION
need to specify anything).
CREATING THE MAKEFILE TEMPLATE
The Makefile Template (Makefile.in) contains three lines:
------------------------------------------------------------------------------
LTLIBRARY_SHARED_NAME = foobar.la
LTLIBRARY_SOURCES = foo.c bar.c
include $(top_srcdir)/build/dynlib.mk
------------------------------------------------------------------------------
LTLIBRARY_SHARED_NAME specifies the name of the extension.
It must be of the form `ext-name.la'.
LTLIBRARY_SOURCES specifies the names of the sources files. You can
name an arbitrary number of source files here.
The final include directive includes the build rules (you usually
don't need to care about what happens there). rules.mk and other
files are installed by phpize which we will cover later.
CREATING THE M4 CONFIGURATION FILE
The m4 configuration can perform additional checks. For a
@@ -87,17 +107,13 @@ PHP_ARG_ENABLE(foobar,whether to enable foobar,
[ --enable-foobar Enable foobar])
if test "$PHP_FOOBAR" != "no"; then
PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared)
PHP_EXTENSION(foobar, $ext_shared)
fi
------------------------------------------------------------------------------
PHP_ARG_ENABLE will automatically set the correct variables, so
that the extension will be enabled by PHP_NEW_EXTENSION in shared mode.
that the extension will be enabled by PHP_EXTENSION in shared mode.
The first argument of PHP_NEW_EXTENSION describes the name of the
extension. The second names the source-code files. The third passes
$ext_shared which is set by PHP_ARG_ENABLE/WITH to PHP_NEW_EXTENSION.
Please use always PHP_ARG_ENABLE or PHP_ARG_WITH. Even if you do not
plan to distribute your module with PHP, these facilities allow you
to integrate your module easily into the main PHP module framework.
@@ -115,9 +131,8 @@ CREATING SOURCE FILES
CREATING THE SELF-CONTAINED EXTENSION
Put config.m4 and the source files into one directory. Then, run phpize
(this is installed during make install by PHP 4.0).
Put Makefile.in, config.m4 and the source files into one directory.
Then run phpize (this is installed during make install by PHP 4.0).
For example, if you configured PHP with --prefix=/php, you would run
$ /php/bin/phpize
@@ -142,13 +157,17 @@ ADDING SHARED MODULE SUPPORT TO A MODULE
support to an existing module called foo.
1. In config.m4, use PHP_ARG_WITH/PHP_ARG_ENABLE. Then you will
automatically be able to use --with-foo=shared[,..] or
--enable-foo=shared[,..].
automatically be able to use --with-foo=shared or
--enable-foo=shared.
2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
2. In config.m4, use PHP_EXTENSION(foo, $ext_shared) to enable
building the extension.
3. Add the following lines to your C source file:
3. Add the following line to Makefile.in:
LTLIBRARY_SHARED_NAME = foo.la
4. Add the following lines to your C source file:
#ifdef COMPILE_DL_FOO
ZEND_GET_MODULE(foo)
-373
View File
@@ -1,373 +0,0 @@
An Overview of the PHP Streams abstraction
==========================================
$Id$
WARNING: some prototypes in this file are out of date.
The information contained here is being integrated into
the PHP manual - stay tuned...
Please send comments to: Wez Furlong <wez@thebrainroom.com>
Why Streams?
============
You may have noticed a shed-load of issock parameters flying around the PHP
code; we don't want them - they are ugly and cumbersome and force you to
special case sockets and files every time you need to work with a "user-level"
PHP file pointer.
Streams take care of that and present the PHP extension coder with an ANSI
stdio-alike API that looks much nicer and can be extended to support non file
based data sources.
Using Streams
=============
Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
FILE* parameter.
The main functions are:
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
count);
PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
const char * fmt, ...);
PHPAPI int php_stream_eof(php_stream * stream);
PHPAPI int php_stream_getc(php_stream * stream);
PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
PHPAPI int php_stream_close(php_stream * stream);
PHPAPI int php_stream_flush(php_stream * stream);
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
PHPAPI off_t php_stream_tell(php_stream * stream);
These (should) behave in the same way as the ANSI stdio functions with similar
names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell.
Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
int options, char **opened_path TSRMLS_DC);
Where:
path is the file or resource to open.
mode is the stdio compatible mode eg: "wb", "rb" etc.
options is a combination of the following values:
IGNORE_PATH (default) - don't use include path to search for the file
USE_PATH - use include path to search for the file
IGNORE_URL - do not use plugin wrappers
REPORT_ERRORS - show errors in a standard format if something
goes wrong.
STREAM_MUST_SEEK - If you really need to be able to seek the stream
and don't need to be able to write to the original
file/URL, use this option to arrange for the stream
to be copied (if needed) into a stream that can
be seek()ed.
opened_path is used to return the path of the actual file opened,
but if you used STREAM_MUST_SEEK, may not be valid. You are
responsible for efree()ing opened_path. opened_path may be (and usually
is) NULL.
If you need to open a specific stream, or convert standard resources into
streams there are a range of functions to do this defined in php_streams.h.
A brief list of the most commonly used functions:
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
Convert a FILE * into a stream.
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
Open a FILE * with tmpfile() and convert into a stream.
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
const char *pfx, char **opened_path TSRMLS_DC);
Generate a temporary file name and open it.
There are some network enabled relatives in php_network.h:
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
Convert a socket into a stream.
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, int timeout, int persistent);
Open a connection to a host and return a stream.
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
struct timeval *timeout);
Open a UNIX domain socket.
Stream Utilities
================
If you need to copy some data from one stream to another, you will be please
to know that the streams API provides a standard way to do this:
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
php_stream *dest, size_t maxlen);
If you want to copy all remaining data from the src stream, pass
PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
number of bytes to copy.
This function will try to use mmap where available to make the copying more
efficient.
If you want to read the contents of a stream into an allocated memory buffer,
you should use:
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
size_t maxlen, int persistent);
This function will set buf to the address of the buffer that it allocated,
which will be maxlen bytes in length, or will be the entire length of the
data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
The buffer is allocated using pemalloc(); you need to call pefree() to
release the memory when you are done.
As with copy_to_stream, this function will try use mmap where it can.
If you have an existing stream and need to be able to seek() it, you
can use this function to copy the contents into a new stream that can
be seek()ed:
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
It returns one of the following values:
#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
make_seekable will always set newstream to be the stream that is valid
if the function succeeds.
When you have finished, remember to close the stream.
NOTE: If you only need to seek forward, there is no need to call this
function, as the php_stream_seek can emulate forward seeking when the
whence parameter is SEEK_CUR.
NOTE: Writing to the stream may not affect the original source, so it
only makes sense to use this for read-only use.
NOTE: If the origstream is network based, this function will block
until the whole contents have been downloaded.
NOTE: Never call this function with an origstream that is referenced
as a resource! It will close the origstream on success, and this
can lead to a crash when the resource is later used/released.
NOTE: If you are opening a stream and need it to be seekable, use the
STREAM_MUST_SEEK option to php_stream_open_wrapper();
Casting Streams
===============
What if your extension needs to access the FILE* of a user level file pointer?
You need to "cast" the stream into a FILE*, and this is how you do it:
FILE * fp;
php_stream * stream; /* already opened */
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
RETURN_FALSE;
}
The prototype is:
PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
show_err);
The show_err parameter, if non-zero, will cause the function to display an
appropriate error message of type E_WARNING if the cast fails.
castas can be one of the following values:
PHP_STREAM_AS_STDIO - a stdio FILE*
PHP_STREAM_AS_FD - a generic file descriptor
PHP_STREAM_AS_SOCKETD - a socket descriptor
If you ask a socket stream for a FILE*, the abstraction will use fdopen to
create it for you. Be warned that doing so may cause buffered data to be lost
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
If your system has the fopencookie function, php streams can synthesize a
FILE* on top of any stream, which is useful for SSL sockets, memory based
streams, data base streams etc. etc.
In situations where this is not desirable, you should query the stream
to see if it naturally supports FILE *. You can use this code snippet
for this purpose:
if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
/* can safely cast to FILE* with no adverse side effects */
}
You can use:
PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
to find out if a stream can be cast, without actually performing the cast, so
to check if a stream is a socket you might use:
if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
/* it can be a socket */
}
Please note the difference between php_stream_is and php_stream_can_cast;
stream_is tells you if the stream is a particular type of stream, whereas
can_cast tells you if the stream can be forced into the form you request.
The former doesn't change anything, while the later *might* change some
state in the stream.
Stream Internals
================
There are two main structures associated with a stream - the php_stream
itself, which holds some state information (and possibly a buffer) and a
php_stream_ops structure, which holds the "virtual method table" for the
underlying implementation.
The php_streams ops struct consists of pointers to methods that implement
read, write, close, flush, seek, gets and cast operations. Of these, an
implementation need only implement write, read, close and flush. The gets
method is intended to be used for streams if there is an underlying method
that can efficiently behave as fgets. The ops struct also contains a label
for the implementation that will be used when printing error messages - the
stdio implementation has a label of "STDIO" for example.
The idea is that a stream implementation defines a php_stream_ops struct, and
associates it with a php_stream using php_stream_alloc.
As an example, the php_stream_fopen() function looks like this:
PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
{
FILE * fp = fopen(filename, mode);
php_stream * ret;
if (fp) {
ret = php_stream_alloc(&php_stream_stdio_ops, fp, 0, 0, mode);
if (ret)
return ret;
fclose(fp);
}
return NULL;
}
php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
FILE* based streams.
A socket based stream would use code similar to that above to create a stream
to be passed back to fopen_wrapper (or it's yet to be implemented successor).
The prototype for php_stream_alloc is this:
PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
size_t bufsize, int persistent, const char * mode)
ops is a pointer to the implementation,
abstract holds implementation specific data that is relevant to this instance
of the stream,
bufsize is the size of the buffer to use - if 0, then buffering at the stream
level will be disabled (recommended for underlying sources that implement
their own buffering - such a FILE*),
persistent controls how the memory is to be allocated - persistently so that
it lasts across requests, or non-persistently so that it is freed at the end
of a request (it uses pemalloc),
mode is the stdio-like mode of operation - php streams places no real meaning
in the mode parameter, except that it checks for a 'w' in the string when
attempting to write (this may change).
The mode parameter is passed on to fdopen/fopencookie when the stream is cast
into a FILE*, so it should be compatible with the mode parameter of fopen().
Writing your own stream implementation
======================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #1: when writing your own streams: make sure you have configured PHP with
--enable-debug.
I've taken some great pains to hook into the Zend memory manager to help track
down allocation problems. It will also help you spot incorrect use of the
STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
definitions.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #2: Please use the stdio stream as a reference; it will help you
understand the semantics of the stream operations, and it will always
be more up to date than these docs :-)
First, you need to figure out what data you need to associate with the
php_stream. For example, you might need a pointer to some memory for memory
based streams, or if you were making a stream to read data from an RDBMS like
MySQL, you might want to store the connection and rowset handles.
The stream has a field called abstract that you can use to hold this data.
If you need to store more than a single field of data, define a structure to
hold it, allocate it (use pemalloc with the persistent flag set
appropriately), and use the abstract pointer to refer to it.
For structured state you might have this:
struct my_state {
MYSQL conn;
MYSQL_RES * result;
};
struct my_state * state = pemalloc(sizeof(struct my_state), persistent);
/* initialize the connection, and run a query, using the fields in state to
* hold the results */
state->result = mysql_use_result(&state->conn);
/* now allocate the stream itself */
stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
/* now stream->abstract == state */
Once you have that part figured out, you can write your implementation and
define the your own php_stream_ops struct (we called it my_ops in the above
example).
For example, for reading from this weird MySQL stream:
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
{
struct my_state * state = (struct my_state*)stream->abstract;
if (buf == NULL && count == 0) {
/* in this special case, php_streams is asking if we have reached the
* end of file */
if (... at end of file ...)
return EOF;
else
return 0;
}
/* pull out some data from the stream and put it in buf */
... mysql_fetch_row(state->result) ...
/* we could do something strange, like format the data as XML here,
and place that in the buf, but that brings in some complexities,
such as coping with a buffer size too small to hold the data,
so I won't even go in to how to do that here */
}
Implement the other operations - remember that write, read, close and flush
are all mandatory. The rest are optional. Declare your stream ops struct:
php_stream_ops my_ops = {
php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
php_mysqlop_flush, NULL, NULL, NULL,
"Strange MySQL example"
}
Thats it!
Take a look at the STDIO implementation in streams.c for more information
about how these operations work.
The main thing to remember is that in your close operation you need to release
and free the resources you allocated for the abstract field. In the case of
the example above, you need to use mysql_free_result on the rowset, close the
connection and then use pefree to dispose of the struct you allocated.
You may read the stream->persistent field to determine if your struct was
allocated in persistent mode or not.
vim:tw=78:et
-127
View File
@@ -1,127 +0,0 @@
Submitting Patch for PHP
========================
This document describes how to submit a patch for PHP. Since you are
reading this document, you are willing to submit a patch for PHP.
Please keep reading! Submitting a patch for PHP is easy. The hard
part is making it acceptable for inclusion into our repository. :-)
How to create patch?
--------------------
We are working with CVS. You need to get CVS source to create a patch
that we accept. Visit http://www.php.net/anoncvs.php to get CVS
source. You can check out older versions, but make sure you get
the default branch (i.e. Do not use -r option when you check out the
CVS source)
Read CODING_STANDARDS file before you start working.
Now you are ready to create a patch. Modify source to fix a bug in PHP or
add a new feature to PHP. After you finished editing, please test your
patch. Read README.TESTING for testing.
After you finish testing your patch, take diff file using
"cvs diff > your.patch" command.
Read README.TESTING for submitting a test script for your patch. This is
not strictly required, but it is preferred to submit a test script along
with your patch. Making new test script is very easy. It also helps us
to understand what you have been fixed or added to PHP.
Tips for creating patch
-----------------------
If you would like to fix multiple bugs. It is easier for us if you
could create 1 patch for 1 bug, but this is not strictly required.
Note though that you might get little response, if your patch is
too hard to review.
If you would like change/add many lines, it is better to ask module
maintainer and/or internals@lists.php.net, or pear-dev@lists.php.net if
you are patching PEAR. Official module maintainers can be found in
EXTENSIONS file in PHP source.
If you are new to CVS (Concurrent Versions System), visit
http://cvshome.org/ for details.
Recommended CVS client settings for creating patch file
------------------------------------------------------
Recommended ~/.cvsrc file setting is:
------
cvs -z3
update -d -P
checkout -P
diff -u
------
diff -u means:
-u Use the unified output format.
With this CVS setting, you don't have to worry about adding/deleting
newlines and spaces.
Check list for submitting patch
-------------------------------
- Did you run "make test" to check if your patch didn't break
other features?
- Did you compile PHP with --enable-debug and check the PHP and
web server error logs when you test your patch?
- Did you build PHP for multi-threaded web servers. (Optional)
- Did you create test script for "make test"? (Recommended)
- Did you check your patch is unified format and it does not
contain white space changes? (If you are not using recommended
cvs setting)
- Did you update CVS source before you take final patch?
- Did you read the patch again?
Where to send your patch?
-------------------------
If you are patching C source, send the patch to internals@lists.php.net.
If you are patching a module, you should also send the patch to the
maintainer. Official module maintainers are listed in EXTENSION file
in source.
If you are patching PEAR, send the patch to pear-dev@lists.php.net.
Please add the prefix "[PATCH]" to your email subject and make sure
to include the patch as a MIME attachment even if it is short.
NOTE: only MIME attachments of type 'text/*' are accepted. The
easiest way to acclomplish this, is to make the extension
'.txt'.
Test scripts should be included in the same email.
Explain what has been fixed/added/changed by your patch.
Finally, add the bug Id(s) which can be closed by your patch, if any.
What happens after you submit your patch
--------------------------------------
If your patch is easy to review and has obviously no side-effects,
it might take up to a few hours until someone commits it.
Because this is a volunteer-driven effort, more complex patches will
require more patience on your side.
If you did not receive any feedback in a few days, please consider
resubmitting the description of your patch, along-side with
these questions:
- Is my patch too hard to review? Because of which factors?
- Should I split it up in multiple parts?
- Are there any unwanted whitespace changes?
What happens when your patch is applied?
----------------------------------------
Your name will be included together with your email address in the CVS
commit log. If your patch affects end-users, a brief description
and your name might be added to the NEWS file.
Thank you for submitting patch for PHP!
-307
View File
@@ -1,307 +0,0 @@
[IMPORTANT NOTICE]
------------------
Do _not_ ask to developers why some or all tests are failed under
your environment! Let us know if you find why it fails. Thank you.
[Testing Basics]
----------------
To execute test scripts, you must build PHP with some SAPI, then you
type "make test" to execute all or some test scripts saved under
"tests" directory under source root directory.
Usage:
make test
"make test" basically executes "run-tests.php" script
under the source root (parallel builds will not work). Therefore you
can execute the script as follows:
TEST_PHP_EXECUTABLE=sapi/cli/php \
sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
[Which "php" executable "make test" look for]
---------------------------------------------
You must use TEST_PHP_EXECUTABLE environment variable to explicitly
select the php executable to be used to run the tests. That can either
be the CLI or CGI executable.
"make test" executes "run-tests.php" script with "php" binary. Some
test scripts such as session must be executed by CGI SAPI. Therefore,
you must build PHP with CGI SAPI to perform all tests.
NOTE: PHP binary executing "run-tests.php" and php binary used for
executing test scripts may differ. If you use different PHP binary for
executing "run-tests.php" script, you may get errors.
[Which php.ini is used]
-----------------------
"make test" uses the same php.ini file as it would once installed.
The tests have been written to be independent of that php.ini file,
so if you find a test that is affected by a setting, please report
this, so we can address the issue.
[Which test scripts are executed]
---------------------------------
"run-tests.php" ("make test"), without any arguments executes all
test scripts by extracting all directories named "tests"
from the source root and any subdirectories below. If there are files,
which have a "phpt" extension, "run-tests.php" looks at the sections
in these files, determines whether it should run it, by evaluating
the 'SKIP' section. If the test is eligible for execution, the 'FILE'
section is extracted into a ".php" file (with the same name besides
the extension) and gets executed.
When an argument is given or TESTS environment variable is set, the
GLOB is expanded by the shell and any file with extension "*.phpt" is
regarded as a test file.
Tester can easily execute tests selectively with as follows.
Examples:
./sapi/cli/php run-tests.php ext/mbstring/*
./sapi/cli/php run-tests.php ext/mbstring/020.phpt
[Test results]
--------------
Test results are printed to standard output. If there is a failed test,
the "run-tests.php" script saves the result, the expected result and the
code executed to the test script directory. For example, if
ext/myext/tests/myext.phpt fails to pass, the following files are created:
ext/myext/tests/myext.php - actual test file executed
ext/myext/tests/myext.log - log of test execution (L)
ext/myext/tests/myext.exp - expected output (E)
ext/myext/tests/myext.out - output from test script (O)
ext/myext/tests/myext.diff - diff of .out and .exp (D)
Failed tests are always bugs. Either the test is bugged or not considering
factors applying to the tester's environment, or there is a bug in PHP.
If this is a known bug, we strive to provide bug numbers, in either the
test name or the file name. You can check the status of such a bug, by
going to: http://bugs.php.net/12345 where 12345 is the bug number.
For clarity and automated processing, bug numbers are prefixed by a hash
sign '#' in test names and/or test cases are named bug12345.phpt.
NOTE: The files generated by tests can be selected by setting the
environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
generated use the character in brackets as shown above (default is LEOD).
The php file will be generated always.
NOTE: You can set environment variable TEST_PHP_DETAILED to enable
detailed test information.
[Automated testing]
If you like to keep up to speed, with latest developments and quality
assurance, setting the environment variable NO_INTERACTION to 1, will not
prompt the tester for any user input.
Normally, the exit status of "make test" is zero, regardless of the results
of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
and "make test" will set the exit status ("$?") to non-zero, when an
individual test has failed.
Example script to be run by cron(1):
========== qa-test.sh =============
#!/bin/sh
CO_DIR=$HOME/cvs/php4
MYMAIL=qa-test@domain.com
TMPDIR=/var/tmp
TODAY=`date +"%Y%m%d"`
# Make sure compilation enviroment is correct
CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
export MAKE=gmake
export CC=gcc
# Set test environment
export NO_INTERACTIVITY=1
export REPORT_EXIT_STATUS=1
cd $CO_DIR
cvs update . >>$TMPDIR/phpqatest.$TODAY
./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
$MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
if test $? -gt 0
then
cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
fi
========== end of qa-test.sh =============
NOTE: the exit status of run-tests.php will be 1 when
REPORT_EXIT_STATUS is set. The result of "make test" may be higher
than that. At present, gmake 3.79.1 returns 2, so it is
advised to test for non-zero, rather then a specific value.
[Creating new test files]
-------------------------
Writing test file is very easy if you are used to PHP.
Here is an actual test file from standard module.
===== ext/standard/tests/strings/strtr.phpt =======
--TEST--
strtr() function
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$trans = array("hello"=>"hi", "hi"=>"hello", "a"=>"A", "world"=>"planet");
var_dump(strtr("# hi all, I said hello world! #", $trans));
?>
--EXPECT--
string(32) "# hello All, I sAid hi planet! #"
===== ext/standard/tests/strings/strtr.phpt =======
As you can see the file is devided into several sections. Below is a
list of all possible sections:
"--TEST--" is title of the test (required).
"--SKIPIF--" is condition when to skip this test (optional).
"--POST--" is POST variable passed to test script (optional).
"--GET--" is GET variable passed to test script (optional).
"--INI--" each line contains an ini setting e.g. foo=bar (optional).
"--FILE--" is the test script (required).
"--EXPECT--" is the expected output from the test script (required).
"--EXPECTF--" is an alternative of --EXPECT--. The difference is that
this form uses sscanf for output validation (alternative).
"--EXPECTREGEX--" is an alternative of --EXPECT--. This form allows the tester
to specify the result in a regular expression (alternative).
A test must at least contain the sections TEST, FILE and either EXPECT
or EXPECTF. When a test is called run-test.php takes the name from the
TEST section and writes the FILE section into a ".php" file with the
same name as the ".phpt" file. This ".php" file will then be executed
and its output compared to the contents of the EXPECT section. It is a
good idea to generate output with var_dump() calls.
/ext/standard/tests/strings/str_shuffle.phpt is a good example for using
EXPECTF instead of EXPECT. From time to time the algorithm used for shuffle
changed and sometimes the machine used to execute the code has influence
on the result of shuffle. But it always returns a three character string
detectable by %s. Other scan-able forms are %i for integers, %d for numbers
only, %f for floating point values, %c for single characters and %x for
hexadecimal values.
==== /ext/standard/tests/strings/str_shuffle.phpt ===
--TEST--
Testing str_shuffle.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = '123';
var_dump(str_shuffle($s));
var_dump($s);
?>
--EXPECTF--
string(3) %s
string(3) "123"
==== end of /ext/standard/tests/strings/str_shuffle.phpt ===
/ext/standard/tests/strings/strings001.phpt is a good example for using
EXPECTREGEX instead of EXPECT. This test also shows that in EXPECTREGEX
some characters need to be escaped since otherwise they would be
interpreted as a regular expression.
==== /ext/standard/tests/strings/strings001.phpt ===
--TEST--
Test whether strstr() and strrchr() are binary safe.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = "alabala nica".chr(0)."turska panica";
var_dump(strstr($s, "nic"));
var_dump(strrchr($s," nic"));
?>
--EXPECTREGEX--
string\(18\) \"nica\x00turska panica\"
string\(19\) \" nica\x00turska panica\"
==== end of /ext/standard/tests/strings/strings001.phpt ===
Some tests depend on modules or functions available only in certain versions
or they even require minimum version of php or zend. These tests should be
skipped when the requirement cannot be fullfilled. To achieve this you can
use the SKIPIF section. To tell run-test.php that your test should be skipped
the SKIPIF section must print out the word "skip" followed by a reason why
the test should skip.
==== /ext/exif/tests/exif005.phpt ===
--TEST--
Check for exif_read_data, unusual IFD start
--SKIPIF--
<?php
if (!extension_loaded('exif')) print 'skip exif extension not available';
?>
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example.
* test5.jpg is a 1*1 image that contains an Exif section with ifd = 00000009h
*/
$image = exif_read_data('./ext/exif/tests/test5.jpg','',true,false);
var_dump($image['IFD0']);
?>
--EXPECT--
array(2) {
["ImageDescription"]=>
string(11) "Ifd00000009"
["DateTime"]=>
string(19) "2002:10:18 20:06:00"
}
==== end of /ext/exif/tests/exif005.phpt ===
Test script and SKIPIF code should be directly written into *.phpt. However,
it is recommended to use include files when more test scripts depend on the
same SKIPIF code or when certain test files need the same values for some
input. But no file used by any test should have one of the following
extensions: ".php", ".log", ".exp", ".out" or ".diff".
Tests should be named according to the following list:
Class: Name: Example:
Tests for bugs bug<bugid>.phpt bug17123.phpt
Tests for functions <functionname>.phpt dba_open.phpt
General tests for extensions <extname><no>.phpt dba3.phpt
When you use an include file for the SKIPIF section it should be named
"skipif.inc" and an include file used in the FILE section of many tests
should be named "test.inc".
NOTE: All tests should run correctly with error_reporting(E_ALL) and
display_errors=1. This is the default when called from run-test.php.
If you have a good reason for lowering the error reporting, use --INI--
section and comment this in your testcode.
NOTE: If your test intentionally generates a PHP warning message use
$php_errormsg variable, which you can then output. This will result
in a consistent error message output across all platforms and PHP
configurations, preventing your test from failing due inconsistencies
in the error message content.
[How to help us]
----------------
If you find bug in PHP, you can submit bug report AND test script
for us. You don't have to write complete script, just give us test
script with following format. Please test the script and make sure
you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
submit.
<?php
/*
Bug #12345
substr() bug. Do not return expected string.
ACTUAL OUTPUT
XYXA
EXPECTED OUTPUT
ABCD
*/
$str = "XYZABCD";
echo substr($str,3,7);
?>
-123
View File
@@ -1,123 +0,0 @@
PHP Build System V5 Overview
- supports Makefile.ins during transition phase
- not-really-portable Makefile includes have been eliminated
- supports separate build directories without VPATH by using
explicit rules only
- does not waste disk-space/CPU-time for building temporary libraries
=> especially noticeable on slower systems
- slow recursive make replaced with one global Makefile
- eases integration of proper dependencies
- adds PHP_DEFINE(what[, value]) which creates a single include-file
per what. This will allow more fine-grained dependencies.
- abandoning the "one library per directory" concept
- improved integration of the CLI
- several new targets
build-modules: builds and copies dynamic modules into modules/
install-cli: installs the CLI only, so that the install-sapi
target does only what its name says
- finally abandoned automake (still requires aclocal at this time)
- changed some configure-time constructs to run at buildconf-time
- upgraded shtool to 1.5.4
- removed $(moduledir) (use EXTENSION_DIR)
The Reason For a New System
It became more and more apparent that there is a severe need
for addressing the portability concerns and improving the chance
that your build is correct (how often have you been told to
"make clean"? When this is done, you won't need to anymore).
If You Build PHP on a Unix System
You, as a user of PHP, will notice no changes. Of course, the build
system will be faster, look better and work smarter.
If You Are Developing PHP
Extension developers:
Makefile.ins are abandoned. The files which are to be compiled
are specified in the config.m4 now using the following macro:
PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
E.g. this enables the extension foo which consists of three source-code
modules, two in C and one in C++. And, depending on the user's wishes,
the extension will even be built as a dynamic module.
The full syntax:
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
Please have a look at acinclude.m4 for the gory details and meanings
of the other parameters.
And that's basically it for the extension side.
If you previously built sub-libraries for this module, add
the source-code files here as well. If you need to specify
separate include directories, do it this way:
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
E.g. this builds the three files which are located relative to the
extension source directory and compiles all three files with the
special include directive (@ext_srcdir@ is automatically replaced).
Now, you need to tell the build system that you want to build files
in a directory called $ext_builddir/lib:
PHP_ADD_BUILD_DIR($ext_builddir/lib)
Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
is only set by the latter.
If you have a complex extension, you might to need add special
Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
in your config.m4 after PHP_NEW_EXTENSION.
This will read a file in the source-dir of your extension called
Makefile.frag. In this file, $(builddir) and $(srcdir) will be
replaced by the values which are correct for your extension
and which are again determined by the PHP_NEW_EXTENSION macro.
Make sure to prefix *all* relative paths correctly with either
$(builddir) or $(srcdir). Because the build system does not
change the working directory anymore, we must use either
absolute paths or relative ones to the top build-directory.
Correct prefixing ensures that.
SAPI developers:
Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
PHP_SELECT_SAPI(name, type, sources.c)
I.e. specify the source-code files as above and also pass the
information regarding how PHP is supposed to be built (shared
module, program, etc).
For example for APXS:
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php4.c php_apache.c)
General info
The foundation for the new system is the flexible handling of
sources and their contexts. With the help of macros you
can define special flags for each source-file, where it is
located, in which target context it can work, etc.
Have a look at the well documented macros
PHP_ADD_SOURCES(_X) in acinclude.m4.
+79 -103
View File
@@ -1,126 +1,102 @@
Using PHP4 with the Zeus Web Server
-----------------------------------
Zeus fully supports running PHP in combination with our
webserver. There are three different interfaces that can be used to
enable PHP:
Zeus fully supports running PHP in combination with our webserver. A
significant improvement in PHP 4 is that you can now run PHP as an
ISAPI module, giving great performance benefits over traditional CGI
code.
* CGI
* ISAPI
* FastCGI
Of the three, we recommend using FastCGI, which has been tested and
benchmarked as providing the best performance and reliability.
Full details of how to install PHP are available from our
website, at:
http://support.zeus.com/products/php.html
If you have any problems, please check the support site for more
up-to-date information and advice.
Note that you will need to be running at least version 3.3.6 of the
webserver. If you are running an earlier version, please see our
website (http://www.zeus.com) for upgrade instructions.
Quick guide to installing FastCGI with Zeus
-------------------------------------------
To build the ISAPI version of PHP, start the configuration with:
Step 1 - obtain and install FastCGI development kit.
./configure --with-zeus=/usr/local/zeus
Grab the package from:
http://www.fastcgi.com/dist/devkit_2.2.0.tar.gz
Obviously, replace /usr/local/zeus with the location of where you have
installed Zeus on your machine. For PHP to build successfully, you
need to have 3.3.6 already installed, because the code relies on the
presence of header files provided with the latest version.
Extract the package and follow the instructions:
./configure
make
make export
(run the last as root)
This will install to /usr/local/lib/libfcgi.a
and /usr/local/include/*fcgi*
You may have to adjust the environment variable LDFLAGS and EXTRA_LIBS
in order to link in extra libraries. This depends on the platform on
which you are building and also on the compiler used (see below). A
standard GNU/Linux install with GCC should build fine with no changes.
Configuring the webserver
-------------------------
Step 2 - Compile PHP as FastCGI.
After running 'make' and 'make install', you will have a 'libphp4.so'
file. Copy this file into a directory reserved for ISAPI
binaries. Now, perform the following steps for each virtual server
that you wish to run PHP on:
Compile as follows:
./configure --with-fastcgi
make
Note that PHP has many options to the configure script -
e.g. --with-mysql. You will probably want to select your usual options
before compiling; the above is just a bare minimum, for illustration.
After compilation finishes, you will be left with an executable
program called 'php'. Copy this into your document root, under a
dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
1) On the Admin server, go to 'edit server->path mapping'
2) Add an alias to the directory with libphp4.so in it, mapped to
/isapi/ (or a location of your choice). Make sure you set the alias
type to ISAPI.
3) Click 'update'
4) Add a handler for file extension 'php' to be run by /isapi/libphp4.so
5) Click 'update', then go back to the previous page.
6) Click on the 'module configuration' button, ensure that ISAPI
support is ticked.
7) Click on the ISAPI link. At the bottom of the page, click the
checkbox for running ISAPI extensions 'out of process'.
8) Click 'update'. Then restart the virtual server. Done!
Step 3 - configure Zeus
Troubleshooting
---------------
Four stages:
- enable FastCGI
- configure FastCGI
- setup alias for FastCGI
- setup alias for PHP
*) Why does the compile fail at Zend/zend-scanner-cc.cc
or Zend/zend-parser.c ?
1) Using the admin server, go to the 'module configuration' page for
your virtual server, and ensure that 'fastcgi' is enabled (select the
tickbox to the left).
These source files are auto-generated from the corresponding .y files.
The default distribution of PHP contains pre-generated versions of these
files that have caused problems for some people. The simplest solution is
to delete the files. They will then be rebuilt correctly. You must have the
following GNU tools to do this:
2) While we can run FastCGI's locally, there are known problems with
some OS's (specifically, the communication between web server and
FastCGI happens over a unix domain socket, and some OS's have trouble
sustaining high connection rates over these sockets). So instead, we
are going to set up the PHP FastCGI to run 'remotely' over localhost
(this uses TCP sockets, which do not suffer this problem). Go to the
'fastcgi configuration' page, and under 'add remote fastcgi':
Add Remote FastCGI
Docroot path /fcgi-bin/php
Remote machine localhost:8002
The first entry is where you saved PHP, above.
The second entry is localhost:<any unused port>
We will start the FastCGI listening on this port shortly.
Click 'update' to commit these changes.
bison 1.28 or later
flex 2.5.4 or later
3) Go to the path mapping module and add an alias for FastCGI:
Add Alias
Docroot path /fcgi-bin
Filesystem directory /path/to/docroot/fcgi-bin
Alias type fastcgi
Click 'update' to commit these changes
*) Why does my PHP library fail to load?
4) Also on the path mapping module, add a handler for PHP:
Add handler
File extension php
Handler /fcgi-bin/php
Click 'update' to commit these changes
After configuring Zeus, if you get a '502 Bad Gateway' error when
accessing a PHP page, there are problems loading the PHP
library. Check the error log ($ZEUSHOME/web/log/errors) for errors.
Finally restart your virtual server for these changes to take effect.
Failing to load the PHP ISAPI module is likely to be due to unresolved
symbols in the module. A way to check for this is to visit our support
page at http://support.zeus.com/faq/entries/isapi_error.html and run
the program there on your libphp4.so. It will list any unresolved
symbols.
*) My libphp4.so has unresolved symbols. How do I fix this?
You must ensure that the PHP build process links in the appropriate
libraries that contain these symbols! The libraries required will
depend on the platform you are running PHP on.
You may need to set one or two environment variables before running
the 'configure' program to set up PHP; LDFLAGS and EXTRA_LIBS. Make
sure that you also export these variables to the build process.
(Type 'export LDFLAGS EXTRA_LIBS' in the shell to do this.)
Specific examples:
Solaris + gcc:
Ensure you run ./configure with the `--enable-libgcc' parameter. You
may need to set LDFLAGS to '-L/usr/local/egcs/lib' (path depends on
your gcc installation)
FreeBSD 4.0:
Some people may find they need to run ./configure with the
'--enable-libgcc' compile option too.
Step 4 - start PHP as a FastCGI runner
When you start PHP, it will pre-fork a given number of child processes
to handle incoming PHP requests. Each process will handle a given
number of requests before exiting (and being replaced by a newly
forked process). You can control these two parameters by setting the
following environment variables BEFORE starting the FastCGI runner:
PHP_FCGI_CHILDREN - the number of child processes to pre-fork. If not
set, defaults to 8.
PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
handles before exiting. If not set, defaults to 500.
To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
8002 $DOCROOT/fcgi-bin/php'. Substitute the appropriate values for
$ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
above.
To stop the runner (e.g. to experiment with the above environment
variables) you will need to manually stop and running PHP
processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
of children and not the runner, Zeus unfortunately cannot keep track
of what processes are running, sorry. A typical command line may look
like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
'{print $4}' | xargs kill'
For more information and help with Zeus, please visit our website:
http://www.zeus.com
+51 -117
View File
@@ -3,167 +3,101 @@ parenthesis means that person has taken on this project.
Zend
----
For PHP 4.3.0:
* Allow foreach ($array as $k => &$val) syntax. right now we cannot
* allow foreach ($array as $k => &$val) syntax. right now we cannot
traverse an array without copying each element.
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
dimensional arrays.
* Look at replacing c-lib call tolower().
* Make hash API functions work with HASH_OF() to save time.
* Allow to set a default value for call-by-reference-parameters.
eg: function hello (&$pallo = NULL) {}
* Disallow function(method) redefinition in class.
* Add configure test to determine if dlsym() requires underscore and set
DLSYM_NEEDS_UNDERSCORE accordingly. Perl and zsh have it in configure,
for example. (DONE?)
For PHP 5.0.0:
* Native large number support (probably with GNU GMP)
* Const'ify APIs. Right now, many functions leave parameters untouched,
but don't declare those as const. This makes interaction with other
interfaces difficult which pass const parameters to us.
* look at replacing c-lib call tolower().
* make hash API functions work with HASH_OF() to save time.
global
------
For PHP 4.3.0:
* Add aliases to functions to conform to new naming conventions, e.g.
str_to_upper().
* Make all extensions thread-safe.
* Make everything on the language-level independent of your locale
settings.
* Change PHP error messages, so that they point to pages or sections
in the PHP Manual.
* Make sure that all ZTS globals get destructed. Most ts_allocate_id()
* make everything on the language-level independent of your locale setings.
* always build the standalone executable as well as the chosen SAPI
target.
* make sure all source files have the "right" copyright.
* the following modules still use PHP3_TLS_*() macros (and thereby don't
work in ZTS mode): ext/dav/dav.c, ext/db/db.c, ext/gd/gd.c, ext/ldap/ldap.c
* INI system causes segfaults in ZTS mode (operates on static HashTable)
* make sure that all ZTS globals get destructed. Most ts_allocate_id()
calls should have a dtor entry.
* Activate all extensions by default that don't rely on external
dependencies. (eg ftp) (DONE?)
* on some platforms unimplemented function will just do nothing
(e.g. symlink) they should print a warning or not even be defined!
(DONE ?)
* Use arg_separator.input to implode args in the CGI sapi extension
and arg_separator.input to explode in php_build_argv(). (DONE?)
For PHP 5.0.0
* bundle and use curl lib for fopen wrapper.
* activate all extensions by default that don't rely on external
dependices. (eg ftp)
* --enable-all in configure. (--enable-shared=max ...)
* make configure print out a summary when it's done (like XEmacs)
* replace standard functions which work on static data with
reentrancy-safe functions (DONE?).
reentrancy-safe functions.
* on some platforms unimplemented function will just do nothing (e.g. symlink)
they should print a warning or not even be defined!
* implement javadoc based function docs template system.
* use thread-safe resolver functions (either require BIND 8 or adns).
* provide optional IPv6 support.
* make SAPI conform to CGI/1.1. Currently, all SAPI modules
define REMOTE_ADDR etc. themselves and reach only various level
of compliance.
* see what functions might need to be changed to use HashPosition, so
that the internal array pointer is not affected.
* Move most extensions and PEAR packages out of the PHP CVS tree,
include them again during release packaging.
Other
* use thread-safe resolver functions (either require BIND 8 or adns).
* implement javadoc based function docs template system.
* provide optional IPv6 support.
* find a better way to implement script timeouts. SIGVTALRM is used
by some POSIX threads implementations (i.e. OpenBSD) and is not
available in ZTS mode.
* Implement flush feature suitable for nested output buffers.
* add aliases to functions to conform to new naming conventions, e.g.
str_to_upper().
* see what functions might need to be changed to use HashPosition, so
that the internal array pointer is not affected.
documentation
-------------
* Add remarks in the documentation which functions are not implemented
on win32.
* Add remarks in the documentation which functions are not binary-safe.
* Update curl documentation (DONE?)
* Add developer documentation.
* Add detailed documentation for Java extension.
* add remarks in the documentation which functions are not implemented on win32.
* add remarks in the documentation which functions are not binary-safe.
ext/bz2
-------
* Add an ini directive to specify the size of decompression buffer.
The default 4k is too small for large files and also requires much time
for decompression. 40k is suitable for such files, however it may be too
much under certain environments. There should be appropriate default
settings for the various SAPI modules (e.g. apache and cli).
ext/curl
ext/dav
--------
* Have a warning scheme for when people use unsupported features.
* rewrite.
ext/mcrypt
----------
* port to mcrypt-2.6 or later
ext/oci8
--------
* All OCIFetch*() functions should return 0 for no more data and false on
error.
* Have a flag that trims trailing spaces from CHAR fields on retrieval.
* Make allow_call_time_pass_reference=Off working.
* For additional todo information, see oci8.c, in ext/oci8
ext/odbc
--------
For PHP 4.3.0:
* update all php_error calls to php_error_docref where valid
* integrate EXPERIMENTAL ODBC update for use in PHP 5.0, use for
testing purposes only.
For PHP 5.0.0
* Activate EXPERIMENTAL ODBC codebase update
* all OCIFetch*() functions should return 0 for no more data and false on error.
* have a flag that trims trailing spaces from CHAR fields on retrieval.
* make allow_call_time_pass_reference=Off working.
ext/pcre
--------
* Allow user to set PCRE_NOTEMPTY, PCRE_ANCHORED at execution time, maybe
ext/pcntl
---------
* Change internal callback handler to use TICKS
* Remove all zend_extension code
* Add object callback support to pcntl_signal()
ext/pgsql
---------
For PHP 4.3.0:
* Add pg_metadata() with metadata cache feature.
* Add pg_convert() to check and convert array value for query.
* Add pg_insert/pg_update/pg_delete/pg_select for simple query.
* have an option for preg_grep() to return keys as well.
* update the online docs from version 3.1 man page
ext/session
-----------
For PHP 4.3.0:
* session_abort() to abort session. ie: Do not save session data.
* Allow unset($_SESSION) or unset($HTTP_SESSION_VARS) to unset
session vars regardless of register_globals setting.
Other:
* Maybe implement finer-grained session variables that could be
* implement a call to set a session read-only to overcome
the need to serialize frame-loads.
* maybe implement finer-grained session variables that could be
locked individually.
* Write a network-transparent storage back-end with fallover
* write a network-transparent storage back-end with fallover
facilities
* Provide a callback facility which is executed upon encountering
an unknown class name during deserialization
ext/sockets
-----------
* Implement IPv6
* Review/Fix vectors
ext/standard
------------
* Add a version number to data serialized via serialize().
* Possibly modify parsing of GPC data to automatically create arrays if
* add a version number to data serialized via serialize().
* array_add(). (Andrei)
* possibly modify parsing of GPC data to automatically create arrays if
variable name is seen more than once.
* Implement regex-cache for url-functions.
* stri_replace(). (Andrei)
* Move socket related functions to fsock.c.
* implement regex-cache for url-functions.
* strcase_replace(). (Andrei)
* move socket related functions to fsock.c.
* get_defined_funcs(), get_defined_vars().
* NOT binary safe:
strtok()
basename()
dirname()
strrpos()
strrchr()
strip_tags()
ext/wddx
--------
* See if we can support the remaining data types:
* See if we can support the remaining datatypes:
dateTime
binary
recordset
http://www.wddx.org/WDDX_SDK_10a/7__References/WDDX_DTD.htm
(Andrei)
-114
View File
@@ -1,114 +0,0 @@
This is an overview over existing segfaults in the current PHP source
tree.
Fixed:
mb_convert_encoding (Moriyoshi)
socket_iovec_alloc (Rasmus)
exif_imagetype,exif_thumbnail (Rasmus)
dbase_open (Rasmus)
array_pad (Rasmus)
setlocale (Rasmus)
unregister_tick_function (Rasmus)
bcsub (Rasmus)
str_repeat (Ilia)
imagecopyresized (Ilia)
mhash_keygen_s2k (Ilia)
bundled gd (Ilia)
mb_ereg, mb_ereg_match, mb_eregi, mb_split (Moriyoshi)
xml_parser_create (Moriyoshi)
ob_start (Sascha)
imagecreate/-truecolor (Sascha)
flock (Sascha)
register_shutdown_function (Sascha)
mb_strcut('', [number greater than the length of first arg]) (Moriyoshi)
ext/exif, ext/dba (Marcus)
php_base64_encode (Moriyoshi)
Open:
the dbase extension (1)
socket_select (2)
pack (3)
(1) heap corruption, mostly visible in malloc-related calls. Whether you see
this or not might depend on your libc/compiler. Hard to track down,
because the result of the corruption might be quite delayed.
Reproducable with glibc-2.3/gcc 3.2.2 by:
cat <<X | php do_crash
dbase_add_record
dbase_close
dbase_create
dbase_delete_record
dbase_get_record
dbase_get_record_with_names
dbase_numfields
dbase_numrecords
dbase_open
X
(2) heap corruption, dies in efree()/execute()
Methodology
1. Use a plain PHP_4_3 tree
2. Use the config.nice from ammendment 1.
3. Download the test script from:
<URL:http://schumann.cx/do_crash.txt>
4a. Use the scripts funcparse.awk/genfunclist.sh from phpdoc/scripts
for creating a plain text function list. Feed that list to
the script. Avoid calls like pcntl_fork. Manually remove functions
which take too long to finish/eat up all memory.
4b. For testing a single function, echo the name of the function to
the script like this:
echo dbase_open | php do_crash.txt
(3) multiple integer overflows, ex. pack("d4294967297", 2);
Amendment 1.
CFLAGS='-O0 -g' \
'../src/php4/configure' \
'--enable-pcntl' \
'--enable-shmop' \
'--enable-sysvsem' \
'--enable-sysvshm' \
'--enable-wddx' \
'--enable-yp' \
'--enable-filepro' \
'--enable-ftp' \
'--enable-dba' \
'--enable-dbase' \
'--enable-dio' \
'--enable-exif' \
'--enable-mbstring' \
'--enable-mbregex' \
'--enable-sockets' \
'--enable-bcmath' \
'--enable-calendar' \
'--enable-pcntl' \
'--enable-shmop' \
'--enable-sysvsem' \
'--enable-sysvshm' \
'--enable-wddx' \
'--enable-yp' \
'--enable-filepro' \
'--enable-ftp' \
'--enable-dba' \
'--enable-dbase' \
'--enable-dio' \
'--enable-exif' \
'--enable-mbstring' \
'--enable-mbregex' \
'--enable-sockets' \
'--enable-bcmath' \
'--enable-calendar' \
"$@"
+73 -248
View File
@@ -15,6 +15,7 @@
#ifdef ZTS
#include <stdio.h>
#include <stdlib.h>
#if HAVE_STDARG_H
#include <stdarg.h>
@@ -38,90 +39,36 @@ typedef struct {
/* The memory manager table */
static tsrm_tls_entry **tsrm_tls_table=NULL;
static tsrm_tls_entry **tsrm_tls_table;
static int tsrm_tls_table_size;
static ts_rsrc_id id_count;
/* The resource sizes table */
static tsrm_resource_type *resource_types_table=NULL;
static tsrm_resource_type *resource_types_table;
static int resource_types_table_size;
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
/* New thread handlers */
static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler;
static tsrm_thread_end_func_t tsrm_new_thread_end_handler;
static void (*tsrm_new_thread_begin_handler)();
static void (*tsrm_new_thread_end_handler)();
/* Debug support */
int tsrm_error(int level, const char *format, ...);
static int tsrm_debug(const char *format, ...);
static int tsrm_debug_status;
/* Read a resource from a thread's resource storage */
static int tsrm_error_level;
static FILE *tsrm_error_file;
#if TSRM_DEBUG
#define TSRM_ERROR(args) tsrm_error args
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
{ \
int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \
\
if (offset==0) { \
return &array; \
} else if ((unshuffled_offset)>=0 && (unshuffled_offset)<(range)) { \
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - 0x%0.8X", \
unshuffled_offset, (long) thread_resources->thread_id, array[unshuffled_offset])); \
return array[unshuffled_offset]; \
} else { \
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", \
unshuffled_offset, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \
return NULL; \
} \
}
#else
#define TSRM_ERROR(args)
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
if (offset==0) { \
return &array; \
} else { \
return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \
}
#endif
#if defined(PTHREADS)
/* Thread local storage */
static pthread_key_t tls_key;
#elif defined(TSRM_ST)
static int tls_key;
#elif defined(TSRM_WIN32)
static DWORD tls_key;
#elif defined(BETHREADS)
static int32 tls_key;
#endif
/* Startup TSRM (call once for the entire process) */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_status)
{
#if defined(GNUPTH)
pth_init();
#elif defined(PTHREADS)
pthread_key_create( &tls_key, 0 );
#elif defined(TSRM_ST)
st_init();
st_key_create(&tls_key, 0);
#elif defined(TSRM_WIN32)
tls_key = TlsAlloc();
#elif defined(BETHREADS)
tls_key = tls_allocate();
#endif
tsrm_error_file = stderr;
tsrm_error_set(debug_level, debug_filename);
tsrm_tls_table_size = expected_threads;
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
if (!tsrm_tls_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
return 0;
}
id_count=0;
@@ -129,9 +76,7 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
resource_types_table_size = expected_resources;
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
if (!resource_types_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"));
free(tsrm_tls_table);
tsrm_tls_table = NULL;
return 0;
}
@@ -139,7 +84,9 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
tsrm_debug_status = debug_status;
tsrm_debug("Started up TSRM, %d expected threads, %d expected resources\n", expected_threads, expected_resources);
return 1;
}
@@ -157,16 +104,7 @@ TSRM_API void tsrm_shutdown(void)
int j;
next_p = p->next;
for (j=0; j<p->count; j++) {
/* Disabled - calling dtors in tsrm_shutdown makes
modules registering TSRM ids to crash, if they have
dtors, since the module is unloaded before tsrm_shutdown
is called. Can be re-enabled after tsrm_free_id is
implemented.
if (resource_types_table && resource_types_table[j].dtor) {
resource_types_table[j].dtor(p->storage[j], &p->storage);
}
*/
for (j=0; j<id_count; j++) {
free(p->storage[j]);
}
free(p->storage);
@@ -175,56 +113,43 @@ TSRM_API void tsrm_shutdown(void)
}
}
free(tsrm_tls_table);
tsrm_tls_table = NULL;
}
if (resource_types_table) {
free(resource_types_table);
resource_types_table=NULL;
}
tsrm_mutex_free(tsmm_mutex);
tsmm_mutex = NULL;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM"));
if (tsrm_error_file!=stderr) {
fclose(tsrm_error_file);
}
tsrm_debug("Shutdown TSRM\n");
#if defined(GNUPTH)
pth_kill();
#elif defined(PTHREADS)
pthread_setspecific(tls_key, 0);
pthread_key_delete(tls_key);
#elif defined(TSRM_WIN32)
TlsFree(tls_key);
#endif
}
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{
ts_rsrc_id new_id;
int i;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
tsrm_debug("Obtaining a new resource id, %d bytes\n", size);
tsrm_mutex_lock(tsmm_mutex);
/* obtain a resource id */
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
new_id = id_count++;
tsrm_debug("Obtained resource id %d\n", new_id);
/* store the new resource type in the resource sizes table */
if (resource_types_table_size < id_count) {
resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
if (!resource_types_table) {
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
*rsrc_id = 0;
return 0;
return -1;
}
resource_types_table_size = id_count;
}
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
resource_types_table[new_id].size = size;
resource_types_table[new_id].ctor = ctor;
resource_types_table[new_id].dtor = dtor;
/* enlarge the arrays for the already active threads */
for (i=0; i<tsrm_tls_table_size; i++) {
@@ -238,7 +163,7 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
for (j=p->count; j<id_count; j++) {
p->storage[j] = (void *) malloc(resource_types_table[j].size);
if (resource_types_table[j].ctor) {
resource_types_table[j].ctor(p->storage[j], &p->storage);
resource_types_table[j].ctor(p->storage[j]);
}
}
p->count = id_count;
@@ -248,8 +173,8 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
}
tsrm_mutex_unlock(tsmm_mutex);
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
return *rsrc_id;
tsrm_debug("Successfully allocated new resource id %d\n", new_id);
return new_id;
}
@@ -257,38 +182,25 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
{
int i;
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
(*thread_resources_ptr)->count = id_count;
(*thread_resources_ptr)->thread_id = thread_id;
(*thread_resources_ptr)->next = NULL;
#if defined(PTHREADS)
/* Set thread local storage to this new thread resources structure */
pthread_setspecific(tls_key, (void *) *thread_resources_ptr);
#elif defined(TSRM_ST)
st_thread_setspecific(tls_key, (void *) *thread_resources_ptr);
#elif defined(TSRM_WIN32)
TlsSetValue(tls_key, (void *) *thread_resources_ptr);
#elif defined(BETHREADS)
tls_set(tls_key, (void*) *thread_resources_ptr);
#endif
tsrm_mutex_unlock(tsmm_mutex);
if (tsrm_new_thread_begin_handler) {
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
tsrm_new_thread_begin_handler(thread_id);
}
for (i=0; i<id_count; i++) {
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
if (resource_types_table[i].ctor) {
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
}
}
tsrm_mutex_unlock(tsmm_mutex);
if (tsrm_new_thread_end_handler) {
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
tsrm_new_thread_end_handler(thread_id);
}
}
@@ -299,38 +211,14 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
THREAD_T thread_id;
int hash_value;
tsrm_tls_entry *thread_resources;
void *resource;
if (!th_id) {
#if defined(PTHREADS)
/* Fast path for looking up the resources for the current
* thread. Its used by just about every call to
* ts_resource_ex(). This avoids the need for a mutex lock
* and our hashtable lookup.
*/
thread_resources = pthread_getspecific(tls_key);
#elif defined(TSRM_ST)
thread_resources = st_thread_getspecific(tls_key);
#elif defined(TSRM_WIN32)
thread_resources = TlsGetValue(tls_key);
#elif defined(BETHREADS)
thread_resources = (tsrm_tls_entry*)tls_get(tls_key);
#else
thread_resources = NULL;
#endif
if (thread_resources) {
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
/* Read a specific resource from the thread's resources.
* This is called outside of a mutex, so have to be aware about external
* changes to the structure as we read it.
*/
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
}
thread_id = tsrm_thread_id();
} else {
if (th_id) {
thread_id = *th_id;
} else {
thread_id = tsrm_thread_id();
}
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
tsrm_debug("Fetching resource id %d for thread %ld\n", id, (long) thread_id);
tsrm_mutex_lock(tsmm_mutex);
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
@@ -338,7 +226,8 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
if (!thread_resources) {
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
return ts_resource_ex(id, &thread_id);
return ts_resource(id);
/* thread_resources = tsrm_tls_table[hash_value]; */
} else {
do {
if (thread_resources->thread_id == thread_id) {
@@ -348,7 +237,7 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
thread_resources = thread_resources->next;
} else {
allocate_new_resource(&thread_resources->next, thread_id);
return ts_resource_ex(id, &thread_id);
return ts_resource(id);
/*
* thread_resources = thread_resources->next;
* break;
@@ -356,22 +245,22 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
}
} while (thread_resources);
}
resource = thread_resources->storage[id];
tsrm_mutex_unlock(tsmm_mutex);
/* Read a specific resource from the thread's resources.
* This is called outside of a mutex, so have to be aware about external
* changes to the structure as we read it.
*/
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
tsrm_debug("Successfully fetched resource id %d for thread id %ld - %x\n", id, (long) thread_id, (long) resource);
return resource;
}
/* frees all resources allocated for the current thread */
void ts_free_thread(void)
{
tsrm_tls_entry *thread_resources;
int i;
THREAD_T thread_id = tsrm_thread_id();
int hash_value;
tsrm_tls_entry *thread_resources;
tsrm_tls_entry *last=NULL;
tsrm_mutex_lock(tsmm_mutex);
@@ -380,25 +269,20 @@ void ts_free_thread(void)
while (thread_resources) {
if (thread_resources->thread_id == thread_id) {
int i;
for (i=0; i<thread_resources->count; i++) {
if (resource_types_table[i].dtor) {
resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage);
resource_types_table[i].dtor(thread_resources->storage[i]);
}
}
for (i=0; i<thread_resources->count; i++) {
free(thread_resources->storage[i]);
}
free(thread_resources->storage);
if (last) {
last->next = thread_resources->next;
} else {
tsrm_tls_table[hash_value] = thread_resources->next;
tsrm_tls_table[hash_value]=NULL;
}
#if defined(PTHREADS)
pthread_setspecific(tls_key, 0);
#elif defined(TSRM_WIN32)
TlsSetValue(tls_key, 0);
#endif
free(thread_resources);
break;
}
@@ -428,8 +312,6 @@ TSRM_API THREAD_T tsrm_thread_id(void)
{
#ifdef TSRM_WIN32
return GetCurrentThreadId();
#elif defined(NETWARE)
return NXThreadGetId();
#elif defined(GNUPTH)
return pth_self();
#elif defined(PTHREADS)
@@ -438,29 +320,18 @@ TSRM_API THREAD_T tsrm_thread_id(void)
return systhread_current();
#elif defined(PI3WEB)
return PIThread_getCurrent();
#elif defined(TSRM_ST)
return st_thread_self();
#elif defined(BETHREADS)
return find_thread(NULL);
#endif
}
/* Allocate a mutex */
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
TSRM_API MUTEX_T tsrm_mutex_alloc( void )
{
MUTEX_T mutexp;
#ifdef NETWARE
long flags = 0; /* Don't require NX_MUTEX_RECURSIVE, I guess */
NXHierarchy_t order = 0;
NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0);
#endif
MUTEX_T mutexp;
#ifdef TSRM_WIN32
mutexp = malloc(sizeof(CRITICAL_SECTION));
mutexp = malloc(sizeof(CRITICAL_SECTION));
InitializeCriticalSection(mutexp);
#elif defined(NETWARE)
mutexp = NXMutexAlloc(flags, order, &lockInfo); /* return value ignored for now */
#elif defined(GNUPTH)
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
pth_mutex_init(mutexp);
@@ -471,29 +342,20 @@ TSRM_API MUTEX_T tsrm_mutex_alloc(void)
mutexp = crit_init();
#elif defined(PI3WEB)
mutexp = PIPlatform_allocLocalMutex();
#elif defined(TSRM_ST)
mutexp = st_mutex_new();
#elif defined(BETHREADS)
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
mutexp->ben = 0;
mutexp->sem = create_sem(1, "PHP sempahore");
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
printf("Mutex created thread: %d\n",mythreadid());
#endif
return( mutexp );
return( mutexp );
}
/* Free a mutex */
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
TSRM_API void tsrm_mutex_free( MUTEX_T mutexp )
{
if (mutexp) {
if (mutexp) {
#ifdef TSRM_WIN32
DeleteCriticalSection(mutexp);
free(mutexp);
#elif defined(NETWARE)
NXMutexFree(mutexp);
#elif defined(GNUPTH)
free(mutexp);
#elif defined(PTHREADS)
@@ -502,29 +364,24 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
#elif defined(NSAPI)
crit_terminate(mutexp);
#elif defined(PI3WEB)
PISync_delete(mutexp);
#elif defined(TSRM_ST)
st_mutex_destroy(mutexp);
#elif defined(BETHREADS)
delete_sem(mutexp->sem);
free(mutexp);
PISync_delete(mutexp)
#endif
}
}
#ifdef THR_DEBUG
printf("Mutex freed thread: %d\n",mythreadid());
printf("Mutex freed thread: %d\n",mythreadid());
#endif
}
/* Lock a mutex */
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
TSRM_API int tsrm_mutex_lock( MUTEX_T mutexp )
{
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id()));
#if 0
tsrm_debug("Mutex locked thread: %ld\n",tsrm_thread_id());
#endif
#ifdef TSRM_WIN32
EnterCriticalSection(mutexp);
return 1;
#elif defined(NETWARE)
return NXLock(mutexp);
#elif defined(GNUPTH)
return pth_mutex_acquire(mutexp, 0, NULL);
#elif defined(PTHREADS)
@@ -533,25 +390,19 @@ TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
return crit_enter(mutexp);
#elif defined(PI3WEB)
return PISync_lock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_lock(mutexp);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, 1) != 0)
return acquire_sem(mutexp->sem);
return 0;
#endif
}
/* Unlock a mutex */
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
TSRM_API int tsrm_mutex_unlock( MUTEX_T mutexp )
{
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld", tsrm_thread_id()));
#if 0
tsrm_debug("Mutex unlocked thread: %ld\n",tsrm_thread_id());
#endif
#ifdef TSRM_WIN32
LeaveCriticalSection(mutexp);
return 1;
#elif defined(NETWARE)
return NXUnlock(mutexp);
#elif defined(GNUPTH)
return pth_mutex_release(mutexp);
#elif defined(PTHREADS)
@@ -560,17 +411,11 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
return crit_exit(mutexp);
#elif defined(PI3WEB)
return PISync_unlock(mutexp);
#elif defined(TSRM_ST)
return st_mutex_unlock(mutexp);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, -1) != 1)
return release_sem(mutexp->sem);
return 0;
#endif
}
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
TSRM_API void *tsrm_set_new_thread_begin_handler(void (*new_thread_begin_handler)(THREAD_T thread_id))
{
void *retval = (void *) tsrm_new_thread_begin_handler;
@@ -579,7 +424,7 @@ TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_th
}
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler)
TSRM_API void *tsrm_set_new_thread_end_handler(void (*new_thread_end_handler)(THREAD_T thread_id))
{
void *retval = (void *) tsrm_new_thread_end_handler;
@@ -593,45 +438,25 @@ TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread
* Debug support
*/
#if TSRM_DEBUG
int tsrm_error(int level, const char *format, ...)
static int tsrm_debug(const char *format, ...)
{
if (level<=tsrm_error_level) {
if (tsrm_debug_status) {
va_list args;
int size;
fprintf(tsrm_error_file, "TSRM: ");
va_start(args, format);
size = vfprintf(tsrm_error_file, format, args);
size = vprintf(format, args);
va_end(args);
fprintf(tsrm_error_file, "\n");
fflush(tsrm_error_file);
return size;
} else {
return 0;
}
}
#endif
void tsrm_error_set(int level, char *debug_filename)
void tsrm_debug_set(int status)
{
tsrm_error_level = level;
#if TSRM_DEBUG
if (tsrm_error_file!=stderr) { /* close files opened earlier */
fclose(tsrm_error_file);
}
if (debug_filename) {
tsrm_error_file = fopen(debug_filename, "w");
if (!tsrm_error_file) {
tsrm_error_file = stderr;
}
} else {
tsrm_error_file = stderr;
}
#endif
tsrm_debug_status = status;
}
#endif /* ZTS */
+3 -40
View File
@@ -20,7 +20,6 @@ CFG=TSRM - Win32 Debug_TS
!MESSAGE "TSRM - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
!MESSAGE "TSRM - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
@@ -43,7 +42,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "Debug_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "C:\Projects\TSRM" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=1 /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_DEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_DEBUG"
# ADD RSC /l 0x40d /d "_DEBUG"
BSC32=bscmake.exe
@@ -66,7 +65,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
@@ -89,30 +88,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "Release_TS_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "TSRM_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TSDbg"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "TSRM___Win32_Release_TSDbg"
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TSDbg"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TSDbg"
# PROP Intermediate_Dir "Release_TSDbg"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D TSRM_DEBUG=0 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /D "ZTS" /D "_LIB" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x40d /d "NDEBUG"
# ADD RSC /l 0x40d /d "NDEBUG"
BSC32=bscmake.exe
@@ -129,7 +105,6 @@ LIB32=link.exe -lib
# Name "TSRM - Win32 Debug_TS"
# Name "TSRM - Win32 Release_TS"
# Name "TSRM - Win32 Release_TS_inline"
# Name "TSRM - Win32 Release_TSDbg"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
@@ -145,20 +120,12 @@ SOURCE=.\tsrm_strtok_r.c
SOURCE=.\tsrm_virtual_cwd.c
# End Source File
# Begin Source File
SOURCE=.\tsrm_win32.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\readdir.h
# End Source File
# Begin Source File
SOURCE=.\TSRM.h
# End Source File
# Begin Source File
@@ -177,10 +144,6 @@ SOURCE=.\tsrm_strtok_r.h
SOURCE=.\tsrm_virtual_cwd.h
# End Source File
# Begin Source File
SOURCE=.\tsrm_win32.h
# End Source File
# End Group
# End Target
# End Project
+25 -70
View File
@@ -13,16 +13,31 @@
#ifndef TSRM_H
#define TSRM_H
/* #ifndef WIN32 */
#if !defined(WIN32) && !defined(NETWARE)
#ifdef HAVE_CONFIG_H
# undef PACKAGE
# undef VERSION
# include "tsrm_config.h"
# undef PACKAGE
# undef VERSION
#endif
/* Only compile multi-threading functions if we're in ZTS mode */
#ifdef ZTS
#ifdef WIN32
# define TSRM_WIN32
# include "tsrm_config.w32.h"
#endif
#ifdef TSRM_WIN32
# include <windows.h>
#elif defined(GNUPTH)
# include <pth.h>
#elif defined(PTHREADS)
# include <pthread.h>
#endif
typedef int ts_rsrc_id;
#ifdef TSRM_WIN32
# ifdef TSRM_EXPORTS
# define TSRM_API __declspec(dllexport)
@@ -33,34 +48,11 @@
# define TSRM_API
#endif
/* Only compile multi-threading functions if we're in ZTS mode */
#ifdef ZTS
#ifdef TSRM_WIN32
# include <windows.h>
#elif defined(NETWARE)
# include <nks/thread.h>
# include <nks/synch.h>
#elif defined(GNUPTH)
# include <pth.h>
#elif defined(PTHREADS)
# include <pthread.h>
#elif defined(TSRM_ST)
# include <st.h>
#elif defined(BETHREADS)
#include <kernel/OS.h>
#include <TLS.h>
#endif
typedef int ts_rsrc_id;
/* Define THREAD_T and MUTEX_T */
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#elif defined(NETWARE)
# define THREAD_T NXThreadId_t
# define MUTEX_T NXMutex_t *
#elif defined(GNUPTH)
# define THREAD_T pth_t
# define MUTEX_T pth_mutex_t *
@@ -73,20 +65,10 @@ typedef int ts_rsrc_id;
#elif defined(PI3WEB)
# define THREAD_T PIThread *
# define MUTEX_T PISync *
#elif defined(TSRM_ST)
# define THREAD_T st_thread_t
# define MUTEX_T st_mutex_t
#elif defined(BETHREADS)
# define THREAD_T thread_id
typedef struct {
sem_id sem;
int32 ben;
} beos_ben;
# define MUTEX_T beos_ben *
#endif
typedef void (*ts_allocate_ctor)(void *, void ***);
typedef void (*ts_allocate_dtor)(void *, void ***);
typedef void (*ts_allocate_ctor)(void *);
typedef void (*ts_allocate_dtor)(void *);
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
@@ -95,11 +77,11 @@ extern "C" {
#endif
/* startup/shutdown */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_status);
TSRM_API void tsrm_shutdown(void);
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
TSRM_API ts_rsrc_id ts_allocate_id(size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
/* fetches the requested resource for the current thread */
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
@@ -113,16 +95,7 @@ TSRM_API void ts_free_id(ts_rsrc_id id);
/* Debug support */
#define TSRM_ERROR_LEVEL_ERROR 1
#define TSRM_ERROR_LEVEL_CORE 2
#define TSRM_ERROR_LEVEL_INFO 3
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);
TSRM_API int tsrm_error(int level, const char *format, ...);
TSRM_API void tsrm_error_set(int level, char *debug_filename);
TSRM_API void tsrm_debug_set(int status);
/* utility functions */
TSRM_API THREAD_T tsrm_thread_id(void);
@@ -131,31 +104,13 @@ TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
#define TSRMLS_D void ***tsrm_ls
#define TSRMLS_DC , TSRMLS_D
#define TSRMLS_C tsrm_ls
#define TSRMLS_CC , TSRMLS_C
TSRM_API void *tsrm_set_new_thread_begin_handler(void (*new_thread_begin_handler)(THREAD_T thread_id));
TSRM_API void *tsrm_set_new_thread_end_handler(void (*new_thread_end_handler)(THREAD_T thread_id));
#ifdef __cplusplus
}
#endif
#else /* non ZTS */
#define TSRMLS_FETCH()
#define TSRMLS_D void
#define TSRMLS_DC
#define TSRMLS_C
#define TSRMLS_CC
#endif /* ZTS */
#endif /* TSRM_H */
+3 -1
View File
@@ -4,7 +4,7 @@ dnl Minimalistic configure.in for TSRM.
dnl
AC_INIT(TSRM.c)
AM_INIT_AUTOMAKE(TSRM, 1.0, nodefine)
AM_INIT_AUTOMAKE(TSRM, 1.0)
AM_CONFIG_HEADER(tsrm_config.h)
sinclude(tsrm.m4)
@@ -28,4 +28,6 @@ unistd.h \
limits.h
)
AC_DEFINE(ZTS,1,[ ])
AC_OUTPUT(Makefile)
+35 -43
View File
@@ -31,27 +31,24 @@ dnl
dnl Set some magic defines to achieve POSIX threads conformance
dnl
AC_DEFUN(PTHREADS_FLAGS,[
if test -z "$host_alias" && test -n "$host"; then
host_alias=$host
fi
if test -z "$host_alias"; then
AC_MSG_ERROR(host_alias is not set. Make sure to run config.guess)
fi
case $host_alias in
case "$host_alias" in
*solaris*)
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
*freebsd*)
PTHREAD_FLAGS="-D_REENTRANT -D_THREAD_SAFE";;
*linux*)
PTHREAD_FLAGS=-D_REENTRANT;;
PTHREAD_FLAGS="-D_REENTRANT";;
*aix*)
PTHREAD_FLAGS=-D_THREAD_SAFE;;
PTHREAD_FLAGS="-D_THREAD_SAFE";;
*irix*)
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
PTHREAD_FLAGS="-D_POSIX_THREAD_SAFE_FUNCTIONS";;
*hpux*)
PTHREAD_FLAGS=-D_REENTRANT;;
PTHREAD_FLAGS="-D_REENTRANT";;
*sco*)
PTHREAD_FLAGS=-D_REENTRANT;;
PTHREAD_FLAGS="-D_REENTRANT";;
dnl Solves sigwait() problem, creates problems with u_long etc.
dnl PTHREAD_FLAGS="-D_REENTRANT -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE_EXTENDED=1";;
esac
@@ -80,11 +77,11 @@ int main() {
int data = 1;
pthread_mutexattr_init(&mattr);
return pthread_create(&thd, NULL, thread_routine, &data);
} ], [
pthreads_working=yes
} ], [
pthreads_working="yes"
], [
pthreads_working=no
], pthreads_working=no ) ] )dnl
pthreads_working="no"
], pthreads_working="no" ) ] )dnl
dnl
dnl PTHREADS_CHECK()
dnl
@@ -102,44 +99,39 @@ dnl -threads gcc (HP-UX)
dnl
AC_DEFUN(PTHREADS_CHECK,[
if test "$beos_threads" = "1"; then
pthreads_working="yes"
ac_cv_pthreads_cflags=""
else
save_CFLAGS=$CFLAGS
save_LIBS=$LIBS
PTHREADS_ASSIGN_VARS
PTHREADS_CHECK_COMPILE
LIBS=$save_LIBS
CFLAGS=$save_CFLAGS
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
PTHREADS_ASSIGN_VARS
PTHREADS_CHECK_COMPILE
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
ac_cv_pthreads_cflags=
if test "$pthreads_working" != "yes"; then
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
ac_save=$CFLAGS
CFLAGS="$CFLAGS $flag"
PTHREADS_CHECK_COMPILE
CFLAGS=$ac_save
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_cflags=$flag
break
fi
done
fi
AC_CACHE_CHECK(for pthreads_cflags,ac_cv_pthreads_cflags,[
ac_cv_pthreads_cflags=""
if test "$pthreads_working" != "yes"; then
for flag in -kthread -pthread -pthreads -mthreads -Kthread -threads -mt -qthreaded; do
ac_save="$CFLAGS"
CFLAGS="$CFLAGS $flag"
PTHREADS_CHECK_COMPILE
CFLAGS="$ac_save"
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_cflags="$flag"
break
fi
done
fi
])
AC_CACHE_CHECK(for pthreads_lib, ac_cv_pthreads_lib,[
ac_cv_pthreads_lib=
ac_cv_pthreads_lib=""
if test "$pthreads_working" != "yes"; then
for lib in pthread pthreads c_r; do
ac_save=$LIBS
ac_save="$LIBS"
LIBS="$LIBS -l$lib"
PTHREADS_CHECK_COMPILE
LIBS=$ac_save
LIBS="$ac_save"
if test "$pthreads_working" = "yes"; then
ac_cv_pthreads_lib=$lib
ac_cv_pthreads_lib="$lib"
break
fi
done
@@ -147,9 +139,9 @@ fi
])
if test "$pthreads_working" = "yes"; then
threads_result="POSIX-Threads found"
threads_result="POSIX Threads found"
else
threads_result="POSIX-Threads not found"
threads_result="POSIX Threads not found"
fi
])dnl
dnl
+9 -40
View File
@@ -50,42 +50,21 @@ AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
])
AC_DEFUN(TSRM_CHECK_ST,[
if test -r "$1/include/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1/include"
LDFLAGS="$LDFLAGS -L$1/lib"
elif test -r "$1/st.h"; then
CPPFLAGS="$CPPFLAGS -I$1"
LDFLAGS="$LDFLAGS -L$1"
fi
AC_CHECK_HEADERS(st.h,[],[
AC_MSG_ERROR([Sorry[,] I was unable to locate the State Threads header file. Please specify the prefix using --with-tsrm-st=/prefix])
])
LIBS="$LIBS -lst"
AC_MSG_CHECKING(for SGI's State Threads)
AC_MSG_RESULT(yes)
AC_DEFINE(TSRM_ST, 1, [ ])
])
sinclude(threads.m4)
sinclude(TSRM/threads.m4)
AC_DEFUN(TSRM_CHECK_PTHREADS,[
PTHREADS_CHECK
if test "$beos_threads" = "1"; then
AC_DEFINE(BETHREADS, 1, Whether to use native BeOS threads)
else
if test "$pthreads_working" != "yes"; then
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
fi
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
if test "$pthreads_working" != "yes"; then
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
fi
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
])
@@ -95,20 +74,12 @@ dnl For the thread implementations, we always use --with-*
dnl to maintain consistency
AC_ARG_WITH(tsrm-pth,
[ --with-tsrm-pth[=pth-config]
Use GNU Pth.],[
[ --with-tsrm-pth[=pth-config] Use GNU Pth.],[
TSRM_PTH=$withval
],[
TSRM_PTH=no
])
AC_ARG_WITH(tsrm-st,
[ --with-tsrm-st Use SGI's State Threads],[
TSRM_ST=$withval
],[
TSRM_ST=no
])
AC_ARG_WITH(tsrm-pthreads,
[ --with-tsrm-pthreads Use POSIX threads (default)],[
TSRM_PTHREADS=$withval
@@ -120,8 +91,6 @@ test "$TSRM_PTH" = "yes" && TSRM_PTH=pth-config
if test "$TSRM_PTH" != "no"; then
TSRM_CHECK_PTH($TSRM_PTH)
elif test "$TSRM_ST" != "no"; then
TSRM_CHECK_ST($TSRM_ST)
elif test "$TSRM_PTHREADS" != "no"; then
TSRM_CHECK_PTHREADS
fi
-9
View File
@@ -1,9 +0,0 @@
#ifndef TSRM_CONFIG_NW_H
#define TSRM_CONFIG_NW_H
#define HAVE_UTIME 1
/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
/* #define HAVE_ALLOCA 1 */
#endif
-5
View File
@@ -3,11 +3,6 @@
#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
#define HAVE_REALPATH 1
#include <malloc.h>
#include <stdlib.h>
#include <crtdbg.h>
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
+7 -18
View File
@@ -5,30 +5,19 @@
# define TSRM_WIN32
#endif
#ifdef TSRM_WIN32
# include "tsrm_config.w32.h"
#elif defined(NETWARE)
# include "tsrm_config.nw.h"
#else
#ifndef TSRM_WIN32
# include "tsrm_config.h"
# include <sys/param.h>
#else
# include "tsrm_config.w32.h"
#endif
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#ifdef TSRM_WIN32
#include <malloc.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if HAVE_UNISTD_H
-260
View File
@@ -1,260 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "TSRM.h"
#ifdef NETWARE
#ifdef USE_MKFIFO
#include <sys/stat.h>
#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */
#include <nks/fsio.h>
#endif
#include <nks/vm.h>
#include <nks/memory.h>
#include <string.h>
#include "mktemp.h"
/* strtok() call in LibC is abending when used in a different address space -- hence using
PHP's version itself for now : Venkat (30/4/02) */
#include "tsrm_strtok_r.h"
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
#define WHITESPACE " \t"
#define MAX_ARGS 10
TSRM_API FILE* popen(const char *commandline, const char *type)
{
char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
char *filePath = NULL;
char *ptr = NULL;
int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
FILE *stream = NULL;
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
int pipe_handle;
int mode = O_RDONLY;
#else
NXHandle_t pipe_handle;
NXMode_t mode = NX_O_RDONLY;
#endif
NXExecEnvSpec_t envSpec;
NXNameSpec_t nameSpec;
NXVmId_t newVM = 0;
/* Check for validity of input parameters */
if (!commandline || !type)
return NULL;
/* Get temporary file name */
filePath = mktemp(tempName);
/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/
if (!filePath)
return NULL;
/* Set pipe mode according to type -- for now allow only "r" or "w" */
if (strcmp(type, "r") == 0)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
mode = O_RDONLY;
#else
mode = NX_O_RDONLY;
#endif
else if (strcmp(type, "w") == 0)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
mode = O_WRONLY;
#else
mode = NX_O_WRONLY;
#endif
else
return NULL;
#ifdef USE_PIPE_OPEN
pipe_handle = pipe_open(filePath, mode);
/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/
if (pipe_handle == -1)
return NULL;
#elif defined(USE_MKFIFO)
pipe_handle = mkfifo(filePath, mode);
consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
if (pipe_handle == -1)
return NULL;
#else
/*
- NetWare doesn't require first parameter
- Allowing LibC to choose the buffer size for now
*/
err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/
if (err)
return NULL;
#endif
/* Copy the environment variables in preparation for the spawn call */
envCount = NXGetEnvCount() + 1; /* add one for NULL */
env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0);
if (!env)
return NULL;
err = NXCopyEnv(env, envCount);
consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err);
if (err)
{
NXMemFree (env);
return NULL;
}
/* Separate commandline string into words */
consoleprintf ("PHP | popen: commandline = %s\n", commandline);
ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
ptrLen = strlen(ptr);
command = (char*)malloc(ptrLen + 1);
if (!command)
{
NXMemFree (env);
return NULL;
}
strcpy (command, ptr);
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
while (ptr && (argc < MAX_ARGS))
{
ptrLen = strlen(ptr);
argv[argc] = (char*)malloc(ptrLen + 1);
if (!argv[argc])
{
NXMemFree (env);
if (command)
free (command);
for (i = 0; i < argc; i++)
{
if (argv[i])
free (argv[i]);
}
return NULL;
}
strcpy (argv[argc], ptr);
argc++;
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
}
consoleprintf ("PHP | popen: commandline string parsed into tokens\n");
/* Setup the execution environment and spawn new process */
envSpec.esFlags = 0; /* Not used */
envSpec.esArgc = argc;
envSpec.esArgv = (void**)argv;
envSpec.esEnv = (void**)env;
envSpec.esStdin.ssType =
envSpec.esStdout.ssType = NX_OBJ_FIFO;
envSpec.esStderr.ssType = NX_OBJ_FILE;
/*
envSpec.esStdin.ssHandle =
envSpec.esStdout.ssHandle =
envSpec.esStderr.ssHandle = -1;
*/
envSpec.esStdin.ssPathCtx =
envSpec.esStdout.ssPathCtx =
envSpec.esStderr.ssPathCtx = NULL;
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
if (mode == O_RDONLY)
#else
if (mode == NX_O_RDONLY)
#endif
{
envSpec.esStdin.ssPath = filePath;
envSpec.esStdout.ssPath = stdout;
}
else /* Write Only */
{
envSpec.esStdin.ssPath = stdin;
envSpec.esStdout.ssPath = filePath;
}
envSpec.esStderr.ssPath = stdout;
nameSpec.ssType = NX_OBJ_FIFO;
/* nameSpec.ssHandle = 0; */ /* Not used */
nameSpec.ssPathCtx = NULL; /* Not used */
nameSpec.ssPath = argv[0];
consoleprintf ("PHP | popen: environment setup\n");
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err);
if (!err)
/* Get file pointer corresponding to the pipe (file) opened */
stream = fdopen(pipe_handle, type);
/* Clean-up */
if (env)
NXMemFree (env);
if (pipe_handle)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
close(pipe_handle);
#else
NXClose(pipe_handle);
#endif
if (command)
free (command);
for (i = 0; i < argc; i++)
{
if (argv[i])
free (argv[i]);
}
consoleprintf ("PHP | popen: all clean-up done, returning...\n");
return stream;
}
TSRM_API int pclose(FILE* stream)
{
int err = 0;
NXHandle_t fd = 0;
/* Get the process associated with this pipe (file) handle and terminate it */
fd = fileno(stream);
NXClose (fd);
err = fclose(stream);
return err;
}
#endif
+166 -267
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -33,24 +33,16 @@
#ifdef TSRM_WIN32
#include <io.h>
#include "tsrm_win32.h"
#endif
#ifdef NETWARE
/*#include "pipe.h"*/
#include "tsrm_nw.h"
#endif
#ifndef HAVE_REALPATH
#define realpath(x,y) strcpy(y,x)
#endif
#define VIRTUAL_CWD_DEBUG 0
#ifdef ZTS
#include "TSRM.h"
#endif
/* Only need mutex for popen() in Windows and NetWare, because it doesn't chdir() on UNIX */
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
/* Only need mutex for popen() in Windows because it doesn't chdir() on UNIX */
#if defined(TSRM_WIN32) && defined(ZTS)
MUTEX_T cwd_mutex;
#endif
@@ -77,8 +69,7 @@ cwd_state main_cwd_state; /* True global */
#endif
#ifdef TSRM_WIN32
#include <tchar.h>
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
#define TOKENIZER_STRING "/\\"
static int php_check_dots(const char *element, int n)
@@ -92,15 +83,8 @@ static int php_check_dots(const char *element, int n)
(len >= 2 && !php_check_dots(element, len))
#define IS_DIRECTORY_CURRENT(element, len) \
(len == 1 && element[0] == '.')
(len == 1 && ptr[0] == '.')
#elif defined(NETWARE)
/* NetWare has strtok() (in LibC) and allows both slashes in paths, like Windows --
but rest of the stuff is like Unix */
/* strtok() call in LibC is abending when used in a different address space -- hence using
PHP's version itself for now */
/*#define tsrm_strtok_r(a,b,c) strtok((a),(b))*/
#define TOKENIZER_STRING "/\\"
#else
#define TOKENIZER_STRING "/"
@@ -111,12 +95,12 @@ static int php_check_dots(const char *element, int n)
#ifndef IS_DIRECTORY_UP
#define IS_DIRECTORY_UP(element, len) \
(len == 2 && element[0] == '.' && element[1] == '.')
(len == 2 && memcmp(element, "..", 2) == 0)
#endif
#ifndef IS_DIRECTORY_CURRENT
#define IS_DIRECTORY_CURRENT(element, len) \
(len == 1 && element[0] == '.')
(len == 1 && ptr[0] == '.')
#endif
/* define this to check semantics */
@@ -137,15 +121,9 @@ static int php_check_dots(const char *element, int n)
static int php_is_dir_ok(const cwd_state *state)
{
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
struct stat buf;
if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode))
#else
struct stat_libc buf;
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode))
#endif
return (0);
return (1);
@@ -153,26 +131,20 @@ static int php_is_dir_ok(const cwd_state *state)
static int php_is_file_ok(const cwd_state *state)
{
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
struct stat buf;
if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode))
#else
struct stat_libc buf;
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode))
#endif
return (0);
return (1);
}
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals)
{
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
}
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals)
{
CWD_STATE_FREE(&cwd_globals->cwd);
}
@@ -205,9 +177,9 @@ CWD_API void virtual_cwd_startup(void)
main_cwd_state.cwd_length = strlen(cwd);
#ifdef ZTS
ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
cwd_globals_id = ts_allocate_id(sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
#else
cwd_globals_ctor(&cwd_globals TSRMLS_CC);
cwd_globals_ctor(&cwd_globals);
#endif
#if defined(TSRM_WIN32) && defined(ZTS)
@@ -218,7 +190,7 @@ CWD_API void virtual_cwd_startup(void)
CWD_API void virtual_cwd_shutdown(void)
{
#ifndef ZTS
cwd_globals_dtor(&cwd_globals TSRMLS_CC);
cwd_globals_dtor(&cwd_globals);
#endif
#if defined(TSRM_WIN32) && defined(ZTS)
tsrm_mutex_free(cwd_mutex);
@@ -227,9 +199,10 @@ CWD_API void virtual_cwd_shutdown(void)
free(main_cwd_state.cwd); /* Don't use CWD_STATE_FREE because the non global states will probably use emalloc()/efree() */
}
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC)
CWD_API char *virtual_getcwd_ex(int *length)
{
cwd_state *state;
CWDLS_FETCH();
state = &CWDG(cwd);
@@ -262,12 +235,12 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC)
/* Same semantics as UNIX getcwd() */
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC)
CWD_API char *virtual_getcwd(char *buf, size_t size)
{
size_t length;
char *cwd;
cwd = virtual_getcwd_ex(&length TSRMLS_CC);
cwd = virtual_getcwd_ex(&length);
if (buf == NULL) {
return cwd;
@@ -284,7 +257,7 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC)
/* Resolve path relatively to state and put the real path into state */
/* returns 0 for ok, 1 for error */
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath)
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path)
{
int path_length = strlen(path);
char *ptr, *path_copy;
@@ -302,12 +275,9 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
if (path_length == 0)
return (0);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
/* cwd_length can be 0 when getcwd() fails.
* This can happen under solaris when a dir does not have read permissions
* but *does* have execute permissions */
if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
if (use_realpath && realpath(path, resolved_path)) {
#ifndef TSRM_WIN32
if (IS_ABSOLUTE_PATH(path, path_length)) {
if (realpath(path, resolved_path)) {
path = resolved_path;
path_length = strlen(path);
}
@@ -325,7 +295,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
memcpy(ptr, path, path_length);
ptr += path_length;
*ptr = '\0';
if (use_realpath && realpath(tmp, resolved_path)) {
if (realpath(tmp, resolved_path)) {
path = resolved_path;
path_length = strlen(path);
}
@@ -340,13 +310,10 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
#endif
if (IS_ABSOLUTE_PATH(path_copy, path_length)) {
copy_amount = COPY_WHEN_ABSOLUTE(path_copy);
copy_amount = COPY_WHEN_ABSOLUTE;
is_absolute = 1;
#ifdef TSRM_WIN32
} else if (IS_UNC_PATH(path_copy, path_length)) {
copy_amount = 2;
is_absolute = 1;
} else if (IS_SLASH(path_copy[0])) {
} else if(IS_SLASH(path_copy[0])) {
copy_amount = 2;
#endif
}
@@ -366,64 +333,45 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
}
if (state->cwd_length > 0 || IS_ABSOLUTE_PATH(path, path_length)) {
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
while (ptr) {
ptr_length = strlen(ptr);
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
while (ptr) {
ptr_length = strlen(ptr);
if (IS_DIRECTORY_UP(ptr, ptr_length)) {
char save;
if (IS_DIRECTORY_UP(ptr, ptr_length)) {
char save;
save = DEFAULT_SLASH;
save = DEFAULT_SLASH;
#define PREVIOUS state->cwd[state->cwd_length - 1]
while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
!IS_SLASH(PREVIOUS)) {
save = PREVIOUS;
PREVIOUS = '\0';
state->cwd_length--;
}
if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
state->cwd[state->cwd_length++] = save;
state->cwd[state->cwd_length] = '\0';
} else {
PREVIOUS = '\0';
state->cwd_length--;
}
} else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
#ifdef TSRM_WIN32
/* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
if ((state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') ||
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
}
#elif defined(NETWARE)
/* If the token is a volume name, it will have colon at the end -- so, no slash before it */
if (ptr[ptr_length-1] != ':') {
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
}
#else
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
#endif
memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
state->cwd_length += ptr_length;
while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
!IS_SLASH(PREVIOUS)) {
save = PREVIOUS;
PREVIOUS = '\0';
state->cwd_length--;
}
ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
}
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
state->cwd = (char *) realloc(state->cwd, state->cwd_length+1+1);
if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
state->cwd[state->cwd_length++] = save;
state->cwd[state->cwd_length] = '\0';
} else {
PREVIOUS = '\0';
state->cwd_length--;
}
} else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
state->cwd[state->cwd_length] = DEFAULT_SLASH;
state->cwd[state->cwd_length+1] = '\0';
state->cwd_length++;
memcpy(&state->cwd[state->cwd_length+1], ptr, ptr_length+1);
state->cwd_length += (ptr_length+1);
}
} else {
state->cwd = (char *) realloc(state->cwd, path_length+1);
memcpy(state->cwd, path, path_length+1);
state->cwd_length = path_length;
ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
}
if (state->cwd_length == COPY_WHEN_ABSOLUTE) {
state->cwd = (char *) realloc(state->cwd, state->cwd_length+1+1);
state->cwd[state->cwd_length] = DEFAULT_SLASH;
state->cwd[state->cwd_length+1] = '\0';
state->cwd_length++;
}
if (verify_path && verify_path(state)) {
@@ -446,12 +394,14 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
return (ret);
}
CWD_API int virtual_chdir(const char *path TSRMLS_DC)
CWD_API int virtual_chdir(const char *path)
{
return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok, 1)?-1:0;
CWDLS_FETCH();
return virtual_file_ex(&CWDG(cwd), path, php_is_dir_ok)?-1:0;
}
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC)
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path))
{
int length = strlen(path);
char *temp;
@@ -469,7 +419,7 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path
return -1;
}
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
if (length == COPY_WHEN_ABSOLUTE && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
length++;
}
temp = (char *) tsrm_do_alloca(length+1);
@@ -478,63 +428,56 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path
#if VIRTUAL_CWD_DEBUG
fprintf (stderr, "Changing directory to %s\n", temp);
#endif
retval = p_chdir(temp TSRMLS_CC);
retval = p_chdir(temp);
tsrm_free_alloca(temp);
return retval;
}
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC)
{
cwd_state new_state;
char *retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, 1)==0) {
int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;
memcpy(real_path, new_state.cwd, len);
real_path[len] = '\0';
retval = real_path;
} else {
retval = NULL;
}
CWD_STATE_FREE(&new_state);
return retval;
}
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC)
CWD_API char *virtual_realpath(const char *path, char *real_path)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
retval = virtual_file_ex(&new_state, path, verify_path, 1);
retval = virtual_file_ex(&new_state, path, NULL);
if(retval) {
int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;
memcpy(real_path, new_state.cwd, len);
real_path[len] = '\0';
return real_path;
}
return NULL;
}
CWD_API int virtual_filepath(const char *path, char **filepath)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
retval = virtual_file_ex(&new_state, path, php_is_file_ok);
*filepath = new_state.cwd;
return retval;
}
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC)
{
return virtual_filepath_ex(path, filepath, php_is_file_ok TSRMLS_CC);
}
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC)
CWD_API FILE *virtual_fopen(const char *path, const char *mode)
{
cwd_state new_state;
FILE *f;
CWDLS_FETCH();
if (path[0] == '\0') { /* Fail to open empty path */
return NULL;
}
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
virtual_file_ex(&new_state, path, NULL);
f = fopen(new_state.cwd, mode);
@@ -542,32 +485,15 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC)
return f;
}
#if !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 1);
ret = access(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return ret;
}
#endif
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC)
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf)
{
cwd_state new_state;
int ret;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL, 0);
virtual_file_ex(&new_state, filename, NULL);
ret = utime(new_state.cwd, buf);
@@ -576,13 +502,14 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC)
}
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
CWD_API int virtual_chmod(const char *filename, mode_t mode)
{
cwd_state new_state;
int ret;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL, 1);
virtual_file_ex(&new_state, filename, NULL);
ret = chmod(new_state.cwd, mode);
@@ -590,14 +517,15 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
return ret;
}
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC)
#ifndef TSRM_WIN32
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group)
{
cwd_state new_state;
int ret;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL, 0);
virtual_file_ex(&new_state, filename, NULL);
ret = chown(new_state.cwd, owner, group);
@@ -606,20 +534,21 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_
}
#endif
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...)
CWD_API int virtual_open(const char *path, int flags, ...)
{
cwd_state new_state;
int f;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
virtual_file_ex(&new_state, path, NULL);
if (flags & O_CREAT) {
mode_t mode;
va_list arg;
va_start(arg, flags);
mode = (mode_t) va_arg(arg, int);
mode = va_arg(arg, mode_t);
va_end(arg);
f = open(new_state.cwd, flags, mode);
@@ -630,13 +559,14 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...)
return f;
}
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC)
CWD_API int virtual_creat(const char *path, mode_t mode)
{
cwd_state new_state;
int f;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
virtual_file_ex(&new_state, path, NULL);
f = creat(new_state.cwd, mode);
@@ -644,81 +574,49 @@ CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC)
return f;
}
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC)
{
cwd_state old_state;
cwd_state new_state;
int retval;
CWD_STATE_COPY(&old_state, &CWDG(cwd));
virtual_file_ex(&old_state, oldname, NULL, 0);
oldname = old_state.cwd;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, newname, NULL, 0);
newname = new_state.cwd;
retval = rename(oldname, newname);
CWD_STATE_FREE(&old_state);
CWD_STATE_FREE(&new_state);
return retval;
}
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
CWD_API int virtual_stat(const char *path, struct stat *buf)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
virtual_file_ex(&new_state, path, NULL);
retval = stat(new_state.cwd, buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#else
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC)
#ifndef TSRM_WIN32
CWD_API int virtual_lstat(const char *path, struct stat *buf)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
retval = stat(new_state.cwd, (struct stat*)buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 0);
virtual_file_ex(&new_state, path, NULL);
retval = lstat(new_state.cwd, buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC)
CWD_API int virtual_unlink(const char *path)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 0);
virtual_file_ex(&new_state, path, NULL);
retval = unlink(new_state.cwd);
@@ -726,13 +624,14 @@ CWD_API int virtual_unlink(const char *path TSRMLS_DC)
return retval;
}
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC)
CWD_API int virtual_mkdir(const char *pathname, mode_t mode)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 1);
virtual_file_ex(&new_state, pathname, NULL);
#ifdef TSRM_WIN32
retval = mkdir(new_state.cwd);
@@ -743,13 +642,14 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC)
return retval;
}
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC)
CWD_API int virtual_rmdir(const char *pathname)
{
cwd_state new_state;
int retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 0);
virtual_file_ex(&new_state, pathname, NULL);
retval = rmdir(new_state.cwd);
@@ -761,13 +661,14 @@ CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC)
DIR *opendir(const char *name);
#endif
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC)
CWD_API DIR *virtual_opendir(const char *pathname)
{
cwd_state new_state;
DIR *retval;
CWDLS_FETCH();
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 1);
virtual_file_ex(&new_state, pathname, NULL);
retval = opendir(new_state.cwd);
@@ -775,52 +676,15 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC)
return retval;
}
#ifdef TSRM_WIN32
#ifndef TSRM_WIN32
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
return popen_ex(command, type, CWDG(cwd).cwd, NULL);
}
#elif defined(NETWARE)
/* On NetWare, the trick of prepending "cd cwd; " doesn't work so we need to perform
a VCWD_CHDIR() and mutex it
*/
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
char prev_cwd[MAXPATHLEN];
char *getcwd_result;
FILE *retval;
getcwd_result = VCWD_GETCWD(prev_cwd, MAXPATHLEN);
if (!getcwd_result) {
return NULL;
}
#ifdef ZTS
tsrm_mutex_lock(cwd_mutex);
#endif
VCWD_CHDIR(CWDG(cwd).cwd);
retval = popen(command, type);
VCWD_CHDIR(prev_cwd);
#ifdef ZTS
tsrm_mutex_unlock(cwd_mutex);
#endif
return retval;
}
#else /* Unix */
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
CWD_API FILE *virtual_popen(const char *command, const char *type)
{
int command_length;
char *command_line;
char *ptr;
FILE *retval;
CWDLS_FETCH();
command_length = strlen(command);
@@ -843,12 +707,47 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
*ptr++ = ' ';
memcpy(ptr, command, command_length+1);
#ifdef TSRM_WIN32
retval = _popen(command_line, type);
#else
retval = popen(command_line, type);
#endif
free(command_line);
return retval;
}
#else
/* On Windows the trick of prepending "cd cwd; " doesn't work so we need to perform
a real chdir() and mutex it
*/
CWD_API FILE *virtual_popen(const char *command, const char *type)
{
char prev_cwd[MAXPATHLEN];
char *getcwd_result;
FILE *retval;
CWDLS_FETCH();
getcwd_result = getcwd(prev_cwd, MAXPATHLEN);
if (!getcwd_result) {
return NULL;
}
#ifdef ZTS
tsrm_mutex_lock(cwd_mutex);
#endif
chdir(CWDG(cwd).cwd);
retval = _popen(command, type);
chdir(prev_cwd);
#ifdef ZTS
tsrm_mutex_unlock(cwd_mutex);
#endif
return retval;
}
#endif
+81 -150
View File
@@ -1,8 +1,8 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
@@ -22,7 +22,6 @@
#ifndef VIRTUAL_CWD_H
#define VIRTUAL_CWD_H
#include "TSRM.h"
#include "tsrm_config_common.h"
#include <sys/types.h>
@@ -41,43 +40,17 @@
#include <unistd.h>
#endif
#if defined(__osf__) || defined(_AIX)
#include <errno.h>
#endif
#ifdef TSRM_WIN32
#include "readdir.h"
#include <sys/utime.h>
/* mode_t isn't defined on Windows */
typedef unsigned short mode_t;
typedef int mode_t;
#define DEFAULT_SLASH '\\'
#define DEFAULT_DIR_SEPARATOR ';'
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c) (*(c) == '/' || \
(*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))
/* COPY_WHEN_ABSOLUTE also takes path as argument because netware needs it
* to account for volume name that is unique to NetWare absolute paths
*/
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_UNC_PATH(path, len) \
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
#define COPY_WHEN_ABSOLUTE 2
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))
#elif defined(NETWARE)
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#define DEFAULT_SLASH '/'
#define DEFAULT_DIR_SEPARATOR ';'
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#define COPY_WHEN_ABSOLUTE(path) \
(strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */
#define IS_ABSOLUTE_PATH(path, len) \
(strchr(path, ':') != NULL) /* Colon indicates volume name */
(len >= 2 && isalpha(path[0]) && path[1] == ':')
#else
#ifdef HAVE_DIRENT_H
@@ -85,21 +58,13 @@ typedef unsigned short mode_t;
#endif
#define DEFAULT_SLASH '/'
#ifdef __riscos__
#define DEFAULT_DIR_SEPARATOR ';'
#else
#define DEFAULT_DIR_SEPARATOR ':'
#endif
#define IS_SLASH(c) ((c) == '/')
#define IS_SLASH_P(c) (*(c) == '/')
#endif
#ifndef COPY_WHEN_ABSOLUTE
#define COPY_WHEN_ABSOLUTE(path) 0
#define COPY_WHEN_ABSOLUTE 0
#endif
#ifndef IS_ABSOLUTE_PATH
@@ -130,72 +95,52 @@ typedef int (*verify_path_func)(const cwd_state *);
CWD_API void virtual_cwd_startup(void);
CWD_API void virtual_cwd_shutdown(void);
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
CWD_API int virtual_chdir(const char *path TSRMLS_DC);
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC);
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC);
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC);
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC);
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
#else
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC);
CWD_API char *virtual_getcwd_ex(int *length);
CWD_API char *virtual_getcwd(char *buf, size_t size);
CWD_API int virtual_chdir(const char *path);
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path));
CWD_API int virtual_filepath(const char *path, char **filepath);
CWD_API char *virtual_realpath(const char *path, char *real_path);
CWD_API FILE *virtual_fopen(const char *path, const char *mode);
CWD_API int virtual_open(const char *path, int flags, ...);
CWD_API int virtual_creat(const char *path, mode_t mode);
CWD_API int virtual_stat(const char *path, struct stat *buf);
#ifndef TSRM_WIN32
CWD_API int virtual_lstat(const char *path, struct stat *buf);
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC);
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC);
#if !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
#endif
/* On AIX & Tru64 when a file does not exist realpath() returns
* NULL, and sets errno to ENOENT. Unlike in other libc implementations
* the destination is not filled and remains undefined. Therefor, we
* must populate it manually using strcpy as done on systems with no
* realpath() function.
*/
#if defined(__osf__) || defined(_AIX)
static char *php_realpath_hack(char *src, char *dest)
{
char *ret;
if ((ret = realpath(src, dest)) == NULL && errno == ENOENT) {
return strcpy(dest, src);
} else {
return ret;
}
}
#endif
CWD_API int virtual_unlink(const char *path);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode);
CWD_API int virtual_rmdir(const char *pathname);
CWD_API DIR *virtual_opendir(const char *pathname);
CWD_API FILE *virtual_popen(const char *command, const char *type);
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC);
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf);
#endif
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC);
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC);
CWD_API int virtual_chmod(const char *filename, mode_t mode);
#ifndef TSRM_WIN32
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group);
#endif
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath);
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path);
typedef struct _virtual_cwd_globals {
cwd_state cwd;
} virtual_cwd_globals;
#ifdef ZTS
# define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
# define CWDLS_D virtual_cwd_globals *cwd_globals
# define CWDLS_DC , CWDLS_D
# define CWDLS_C cwd_globals
# define CWDLS_CC , CWDLS_C
# define CWDG(v) (cwd_globals->v)
# define CWDLS_FETCH() virtual_cwd_globals *cwd_globals = ts_resource(cwd_globals_id)
#else
# define CWDLS_D void
# define CWDLS_DC
# define CWDLS_C
# define CWDLS_CC
# define CWDG(v) (cwd_globals.v)
# define CWDLS_FETCH()
#endif
/* The actual macros to be used in programs using TSRM
@@ -205,71 +150,57 @@ typedef struct _virtual_cwd_globals {
#ifdef VIRTUAL_DIR
#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
/* Because open() has two modes, we have to macros to replace it */
#define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
#define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
#define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
#define VCWD_GETWD(buf)
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#define V_GETCWD(buff, size) virtual_getcwd(buff,size)
#define V_FOPEN(path, mode) virtual_fopen(path, mode)
/* The V_OPEN macro will need to be used as V_OPEN((path, flags, ...)) */
#define V_OPEN(open_args) virtual_open open_args
#define V_CREAT(path, mode) virtual_creat(path, mode)
#define V_CHDIR(path) virtual_chdir(path)
#define V_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir)
#define V_GETWD(buf)
#define V_REALPATH(path,real_path) virtual_realpath(path,real_path)
#define V_STAT(path, buff) virtual_stat(path, buff)
#ifdef TSRM_WIN32
#define V_LSTAT(path, buff) virtual_stat(path, buff)
#else
#define V_LSTAT(path, buff) virtual_lstat(path, buff)
#endif
#define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
#define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
#define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
#define VCWD_OPENDIR(pathname) virtual_opendir(pathname TSRMLS_CC)
#define VCWD_POPEN(command, type) virtual_popen(command, type TSRMLS_CC)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
#define V_UNLINK(path) virtual_unlink(path)
#define V_MKDIR(pathname, mode) virtual_mkdir(pathname, mode)
#define V_RMDIR(pathname) virtual_rmdir(pathname)
#define V_OPENDIR(pathname) virtual_opendir(pathname)
#define V_POPEN(command, type) virtual_popen(command, type)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
#define V_UTIME(path,time) virtual_utime(path,time)
#endif
#define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group TSRMLS_CC)
#define V_CHMOD(path,mode) virtual_chmod(path,mode)
#ifndef TSRM_WIN32
#define V_CHOWN(path,owner,group) virtual_chown(path,owner,group)
#endif
#else
#define VCWD_GETCWD(buff, size) getcwd(buff, size)
#define VCWD_FOPEN(path, mode) fopen(path, mode)
#define VCWD_OPEN(path, flags) open(path, flags)
#define VCWD_OPEN_MODE(path, flags, mode) open(path, flags, mode)
#define VCWD_CREAT(path, mode) creat(path, mode)
#define VCWD_RENAME(oldname, newname) rename(oldname, newname)
#define VCWD_CHDIR(path) chdir(path)
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define VCWD_GETWD(buf) getwd(buf)
#define VCWD_STAT(path, buff) stat(path, buff)
#define VCWD_LSTAT(path, buff) lstat(path, buff)
#define VCWD_UNLINK(path) unlink(path)
#define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
#define VCWD_RMDIR(pathname) rmdir(pathname)
#define VCWD_OPENDIR(pathname) opendir(pathname)
#define VCWD_POPEN(command, type) popen(command, type)
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#ifdef HAVE_REALPATH
#if defined(__osf__) || defined(_AIX)
#define VCWD_REALPATH(path, real_path) php_realpath_hack(path, real_path)
#else
#define VCWD_REALPATH(path, real_path) realpath(path, real_path)
#endif
#else
#define VCWD_REALPATH(path, real_path) strcpy(real_path, path)
#endif
#define V_GETCWD(buff, size) getcwd(buff,size)
#define V_FOPEN(path, mode) fopen(path, mode)
#define V_OPEN(open_args) open open_args
#define V_CREAT(path, mode) creat(path, mode)
#define V_CHDIR(path) chdir(path)
#define V_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
#define V_GETWD(buf) getwd(buf)
#define V_STAT(path, buff) stat(path, buff)
#define V_LSTAT(path, buff) lstat(path, buff)
#define V_UNLINK(path) unlink(path)
#define V_MKDIR(pathname, mode) mkdir(pathname, mode)
#define V_RMDIR(pathname) rmdir(pathname)
#define V_OPENDIR(pathname) opendir(pathname)
#define V_POPEN(command, type) popen(command, type)
#define V_REALPATH(path,real_path) realpath(path,real_path)
#if HAVE_UTIME
#define VCWD_UTIME(path, time) utime(path, time)
#define V_UTIME(path,time) utime(path,time)
#endif
#define VCWD_CHMOD(path, mode) chmod(path, mode)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
#define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
#define V_CHMOD(path,mode) chmod(path,mode)
#ifndef TSRM_WIN32
#define V_CHOWN(path,owner,group) chown(path,owner,group)
#endif
#endif
-371
View File
@@ -1,371 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <time.h>
#include "TSRM.h"
#ifdef TSRM_WIN32
#include "tsrm_win32.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
#else
static tsrm_win32_globals win32_globals;
#endif
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
{
globals->process = NULL;
globals->shm = NULL;
globals->process_size = 0;
globals->shm_size = 0;
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
}
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
{
shm_pair *ptr;
if (globals->process) {
free(globals->process);
}
if (globals->shm) {
for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
UnmapViewOfFile(ptr->addr);
CloseHandle(ptr->segment);
UnmapViewOfFile(ptr->descriptor);
CloseHandle(ptr->info);
}
free(globals->shm);
}
free(globals->comspec);
}
TSRM_API void tsrm_win32_startup(void)
{
#ifdef ZTS
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
#else
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
#endif
}
TSRM_API void tsrm_win32_shutdown(void)
{
#ifndef ZTS
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
#endif
}
static process_pair *process_get(FILE *stream TSRMLS_DC)
{
process_pair *ptr;
process_pair *newptr;
for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
if (ptr->stream == stream) {
break;
}
}
if (ptr < (TWG(process) + TWG(process_size))) {
return ptr;
}
newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
if (newptr == NULL) {
return NULL;
}
TWG(process) = newptr;
ptr = newptr + TWG(process_size);
TWG(process_size)++;
return ptr;
}
static shm_pair *shm_get(int key, void *addr)
{
shm_pair *ptr;
shm_pair *newptr;
TSRMLS_FETCH();
for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
if (!ptr->descriptor) {
continue;
}
if (!addr && ptr->descriptor->shm_perm.key == key) {
break;
} else if (ptr->addr == addr) {
break;
}
}
if (ptr < (TWG(shm) + TWG(shm_size))) {
return ptr;
}
newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
if (newptr == NULL) {
return NULL;
}
TWG(shm) = newptr;
ptr = newptr + TWG(shm_size);
TWG(shm_size)++;
return ptr;
}
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
HANDLE copy, self = GetCurrentProcess();
if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
return NULL;
}
return copy;
}
TSRM_API FILE *popen(const char *command, const char *type)
{
return popen_ex(command, type, NULL, NULL);
}
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
{
FILE *stream = NULL;
int fno, str_len = strlen(type), read, mode;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
HANDLE in, out;
char *cmd;
process_pair *proc;
TSRMLS_FETCH();
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = TRUE;
security.lpSecurityDescriptor = NULL;
if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) {
return NULL;
}
memset(&startup, 0, sizeof(STARTUPINFO));
memset(&process, 0, sizeof(PROCESS_INFORMATION));
startup.cb = sizeof(STARTUPINFO);
startup.dwFlags = STARTF_USESTDHANDLES;
startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
read = (type[0] == 'r') ? TRUE : FALSE;
mode = ((str_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
if (read) {
in = dupHandle(in, FALSE);
startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startup.hStdOutput = out;
} else {
out = dupHandle(out, FALSE);
startup.hStdInput = in;
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c "));
sprintf(cmd, "%s /c %s", TWG(comspec), command);
if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, env, cwd, &startup, &process)) {
return NULL;
}
free(cmd);
CloseHandle(process.hThread);
proc = process_get(NULL TSRMLS_CC);
if (read) {
fno = _open_osfhandle((long)in, _O_RDONLY | mode);
CloseHandle(out);
} else {
fno = _open_osfhandle((long)out, _O_WRONLY | mode);
CloseHandle(in);
}
stream = _fdopen(fno, type);
proc->prochnd = process.hProcess;
proc->stream = stream;
return stream;
}
TSRM_API int pclose(FILE *stream)
{
DWORD termstat = 0;
process_pair *process;
TSRMLS_FETCH();
if ((process = process_get(stream TSRMLS_CC)) == NULL) {
return 0;
}
fflush(process->stream);
fclose(process->stream);
WaitForSingleObject(process->prochnd, INFINITE);
GetExitCodeProcess(process->prochnd, &termstat);
process->stream = NULL;
CloseHandle(process->prochnd);
return termstat;
}
TSRM_API int shmget(int key, int size, int flags)
{
shm_pair *shm;
char shm_segment[26], shm_info[29];
HANDLE shm_handle, info_handle;
BOOL created = FALSE;
if (size < 0) {
return -1;
}
sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
if ((!shm_handle && !info_handle)) {
if (flags & IPC_EXCL) {
return -1;
}
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
created = TRUE;
}
if ((!shm_handle || !info_handle)) {
return -1;
}
}
shm = shm_get(key, NULL);
shm->segment = shm_handle;
shm->info = info_handle;
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (created) {
shm->descriptor->shm_perm.key = key;
shm->descriptor->shm_segsz = size;
shm->descriptor->shm_ctime = time(NULL);
shm->descriptor->shm_cpid = getpid();
shm->descriptor->shm_perm.mode = flags;
shm->descriptor->shm_perm.cuid = shm->descriptor->shm_perm.cgid= 0;
shm->descriptor->shm_perm.gid = shm->descriptor->shm_perm.uid = 0;
shm->descriptor->shm_atime = shm->descriptor->shm_dtime = 0;
shm->descriptor->shm_lpid = shm->descriptor->shm_nattch = 0;
shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
}
if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
CloseHandle(shm->segment);
UnmapViewOfFile(shm->descriptor);
CloseHandle(shm->info);
return -1;
}
return key;
}
TSRM_API void *shmat(int key, const void *shmaddr, int flags)
{
shm_pair *shm = shm_get(key, NULL);
if (!shm->segment) {
return (void*)-1;
}
shm->descriptor->shm_atime = time(NULL);
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch++;
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
return shm->addr;
}
TSRM_API int shmdt(const void *shmaddr)
{
shm_pair *shm = shm_get(0, (void*)shmaddr);
if (!shm->segment) {
return -1;
}
shm->descriptor->shm_dtime = time(NULL);
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch--;
return UnmapViewOfFile(shm->addr) ? 0 : -1;
}
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
shm_pair *shm = shm_get(key, NULL);
if (!shm->segment) {
return -1;
}
switch (cmd) {
case IPC_STAT:
memcpy(buf, shm->descriptor, sizeof(struct shmid_ds));
return 0;
case IPC_SET:
shm->descriptor->shm_ctime = time(NULL);
shm->descriptor->shm_perm.uid = buf->shm_perm.uid;
shm->descriptor->shm_perm.gid = buf->shm_perm.gid;
shm->descriptor->shm_perm.mode = buf->shm_perm.mode;
return 0;
case IPC_RMID:
if (shm->descriptor->shm_nattch < 1) {
shm->descriptor->shm_perm.key = -1;
}
return 0;
default:
return -1;
}
}
TSRM_API char *realpath(char *orig_path, char *buffer)
{
int ret = GetFullPathName(orig_path, _MAX_PATH, buffer, NULL);
if(!ret || ret > _MAX_PATH) {
return NULL;
}
return buffer;
}
#endif
-105
View File
@@ -1,105 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef TSRM_WIN32_H
#define TSRM_WIN32_H
#include "TSRM.h"
#include <windows.h>
struct ipc_perm {
int key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
unsigned short cgid;
unsigned short mode;
unsigned short seq;
};
struct shmid_ds {
struct ipc_perm shm_perm;
int shm_segsz;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
unsigned short shm_cpid;
unsigned short shm_lpid;
short shm_nattch;
};
typedef struct {
FILE *stream;
HANDLE prochnd;
} process_pair;
typedef struct {
void *addr;
HANDLE info;
HANDLE segment;
struct shmid_ds *descriptor;
} shm_pair;
typedef struct {
process_pair *process;
shm_pair *shm;
int process_size;
int shm_size;
char *comspec;
} tsrm_win32_globals;
#ifdef ZTS
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
#else
# define TWG(v) (win32_globals.v)
#endif
#define IPC_PRIVATE 0
#define IPC_CREAT 00001000
#define IPC_EXCL 00002000
#define IPC_NOWAIT 00004000
#define IPC_RMID 0
#define IPC_SET 1
#define IPC_STAT 2
#define IPC_INFO 3
#define SHM_R PAGE_READONLY
#define SHM_W PAGE_READWRITE
#define SHM_RDONLY FILE_MAP_READ
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
TSRM_API void tsrm_win32_startup(void);
TSRM_API void tsrm_win32_shutdown(void);
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env);
TSRM_API FILE *popen(const char *command, const char *type);
TSRM_API int pclose(FILE *stream);
TSRM_API int shmget(int key, int size, int flags);
TSRM_API void *shmat(int key, const void *shmaddr, int flags);
TSRM_API int shmdt(const void *shmaddr);
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
TSRM_API char *realpath(char *orig_path, char *buffer);
#endif
+186
View File
@@ -0,0 +1,186 @@
// $Header$
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
// by flex
// Copyright (c) 1993 The Regents of the University of California.
// All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
// Redistribution and use in source and binary forms with or without
// modification are permitted provided that: (1) source distributions retain
// this entire copyright notice and comment, and (2) distributions including
// binaries display the following acknowledgement: ``This product includes
// software developed by the University of California, Berkeley and its
// contributors'' in the documentation or other materials provided with the
// distribution and in all advertising materials mentioning features or use
// of this software. Neither the name of the University nor the names of
// its contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// This file defines FlexLexer, an abstract class which specifies the
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
// which defines a particular lexer class.
//
// If you want to create multiple lexer classes, you use the -P flag
// to rename each yyFlexLexer to some other xxFlexLexer. You then
// include <FlexLexer.h> in your other sources once per lexer class:
//
// #undef yyFlexLexer
// #define yyFlexLexer xxFlexLexer
// #include <FlexLexer.h>
//
// #undef yyFlexLexer
// #define yyFlexLexer zzFlexLexer
// #include <FlexLexer.h>
// ...
#ifndef FLEXLEXER_H
// Never included before - need to define base class.
#define FLEXLEXER_H
#include <iostream.h>
extern "C++" {
struct yy_buffer_state;
typedef int yy_state_type;
class FlexLexer {
public:
virtual ~FlexLexer() { }
const char* YYText() { return yytext; }
int YYLeng() { return yyleng; }
virtual void
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
virtual struct yy_buffer_state*
yy_create_buffer( istream* s, int size ) = 0;
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
virtual void yyrestart( istream* s ) = 0;
virtual int yylex() = 0;
// Call yylex with new input/output sources.
int yylex( istream* new_in, ostream* new_out = 0 )
{
switch_streams( new_in, new_out );
return yylex();
}
// Switch to new input/output streams. A nil stream pointer
// indicates "keep the current one".
virtual void switch_streams( istream* new_in = 0,
ostream* new_out = 0 ) = 0;
int lineno() const { return yylineno; }
int debug() const { return yy_flex_debug; }
void set_debug( int flag ) { yy_flex_debug = flag; }
protected:
char* yytext;
int yyleng;
int yylineno; // only maintained if you use %option yylineno
int yy_flex_debug; // only has effect with -d or "%option debug"
};
}
#endif
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
// Either this is the first time through (yyFlexLexerOnce not defined),
// or this is a repeated include to define a different flavor of
// yyFlexLexer, as discussed in the flex man page.
#define yyFlexLexerOnce
class yyFlexLexer : public FlexLexer {
public:
// arg_yyin and arg_yyout default to the cin and cout, but we
// only make that assignment when initializing in yylex().
yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );
virtual ~yyFlexLexer();
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
struct yy_buffer_state* yy_create_buffer( istream* s, int size );
void yy_delete_buffer( struct yy_buffer_state* b );
void yyrestart( istream* s );
virtual int yylex();
virtual void switch_streams( istream* new_in, ostream* new_out );
protected:
virtual int LexerInput( char* buf, int max_size );
virtual void LexerOutput( const char* buf, int size );
virtual void LexerError( const char* msg );
void yyunput( int c, char* buf_ptr );
int yyinput();
void yy_load_buffer_state();
void yy_init_buffer( struct yy_buffer_state* b, istream* s );
void yy_flush_buffer( struct yy_buffer_state* b );
int yy_start_stack_ptr;
int yy_start_stack_depth;
int* yy_start_stack;
void yy_push_state( int new_state );
void yy_pop_state();
int yy_top_state();
yy_state_type yy_get_previous_state();
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
int yy_get_next_buffer();
istream* yyin; // input source for default LexerInput
ostream* yyout; // output sink for default LexerOutput
struct yy_buffer_state* yy_current_buffer;
// yy_hold_char holds the character lost when yytext is formed.
char yy_hold_char;
// Number of characters read into yy_ch_buf.
int yy_n_chars;
// Points to current character in buffer.
char* yy_c_buf_p;
int yy_init; // whether we need to initialize
int yy_start; // start state number
// Flag which is used to allow yywrap()'s to do buffer switches
// instead of setting up a fresh yyin. A bit of a hack ...
int yy_did_buffer_switch_on_eof;
// The following are not always needed, but may be depending
// on use of certain flex features (like REJECT or yymore()).
yy_state_type yy_last_accepting_state;
char* yy_last_accepting_cpos;
yy_state_type* yy_state_buf;
yy_state_type* yy_state_ptr;
char* yy_full_match;
int* yy_full_state;
int yy_full_lp;
int yy_lp;
int yy_looking_for_trail_begin;
int yy_more_flag;
int yy_more_len;
int yy_more_offset;
int yy_prev_more_offset;
};
#endif
+116
View File
@@ -0,0 +1,116 @@
---------------------------------------------------------------------------
The Zend License, version 0.92
Copyright (C) 1999-2000 Zend Technologies Ltd.
---------------------------------------------------------------------------
The Zend scripting engine library is a product of Zend Technologies Ltd.
It may be used and/or distributed under the terms of the Q Public
License (QPL) version 1.0, enclosed below.
For more information about Zend please visit http://www.zend.com/
For license related questions please mail license@zend.com
===========================================================================
THE Q PUBLIC LICENSE
version 1.0
Copyright (C) 1999 Troll Tech AS, Norway.
Everyone is permitted to copy and
distribute this license document.
The intent of this license is to establish freedom to share and change the
software regulated by this license under the open source model.
This license applies to any software containing a notice placed by the
copyright holder saying that it may be distributed under the terms of
the Q Public License version 1.0. Such software is herein referred to as
the Software. This license covers modification and distribution of the
Software, use of third-party application programs based on the Software,
and development of free software which uses the Software.
Granted Rights
1. You are granted the non-exclusive rights set forth in this license
provided you agree to and comply with any and all conditions in this
license. Whole or partial distribution of the Software, or software
items that link with the Software, in any form signifies acceptance of
this license.
2. You may copy and distribute the Software in unmodified form provided
that the entire package, including - but not restricted to - copyright,
trademark notices and disclaimers, as released by the initial developer
of the Software, is distributed.
3. You may make modifications to the Software and distribute your
modifications, in a form that is separate from the Software, such as
patches. The following restrictions apply to modifications:
a. Modifications must not alter or remove any copyright notices in
the Software.
b. When modifications to the Software are released under this
license, a non-exclusive royalty-free right is granted to the
initial developer of the Software to distribute your modification
in future versions of the Software provided such versions remain
available under these terms in addition to any other license(s) of
the initial developer.
4. You may distribute machine-executable forms of the Software or
machine-executable forms of modified versions of the Software, provided
that you meet these restrictions:
a. You must include this license document in the distribution.
b. You must ensure that all recipients of the machine-executable forms
are also able to receive the complete machine-readable source code
to the distributed Software, including all modifications, without
any charge beyond the costs of data transfer, and place prominent
notices in the distribution explaining this.
c. You must ensure that all modifications included in the
machine-executable forms are available under the terms of this
license.
5. You may use the original or modified versions of the Software to
compile, link and run application programs legally developed by you
or by others.
6. You may develop application programs, reusable components and other
software items that link with the original or modified versions of the
Software. These items, when distributed, are subject to the following
requirements:
a. You must ensure that all recipients of machine-executable forms of
these items are also able to receive and use the complete
machine-readable source code to the items without any charge
beyond the costs of data transfer.
b. You must explicitly license all recipients of your items to use
and re-distribute original and modified versions of the items in
both machine-executable and source code forms. The recipients must
be able to do so without any charges whatsoever, and they must be
able to re-distribute to anyone they choose.
c. If the items are not available to the general public, and the
initial developer of the Software requests a copy of the items,
then you must supply one.
Limitations of Liability
In no event shall the initial developers or copyright holders be liable
for any damages whatsoever, including - but not restricted to - lost
revenue or profits or other direct, indirect, special, incidental or
consequential damages, even if they have been advised of the possibility
of such damages, except to the extent invariable law, if any, provides
otherwise.
No Warranty
The Software and this license document are provided AS IS with NO WARRANTY
OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
===========================================================================
+41
View File
@@ -0,0 +1,41 @@
## Process this file with automake to produce Makefile.in -*- makefile -*-
#CLEANFILES = zend-parser.c zend-parser.h zend-scanner.c zend-parser.output
AUTOMAKE_OPTIONS=foreign
EXTRA_LTLIBRARIES=libZend_cc.la libZend_c.la
noinst_LTLIBRARIES=$(ZEND_SCANNER) libZend.la
libZend_cc_la_SOURCES=zend-scanner-cc.cc
libZend_c_la_SOURCES=zend-scanner.c
libZend_la_SOURCES=\
zend-parser.y \
zend_alloc.c zend_compile.c zend_constants.c zend_dynamic_array.c \
zend_execute.c zend_execute_API.c zend_highlight.c zend_llist.c \
zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c
libZend_la_LIBADD = $(ZEND_SCANNER)
libZend_la_LDFLAGS = @EXTRA_LIBS@
libZend_la_DEPENDENCIES = $(ZEND_SCANNER)
# automake isn't too clever about "non-standard" use of lex and yacc
$(libZend_la_OBJECTS) zend-scanner.lo zend-scanner-cc.lo: zend-parser.h
zend-scanner.c: $(srcdir)/zend-scanner.l
$(LEX) -Pzend -o$@ -i $(srcdir)/zend-scanner.l
zend-scanner-cc.cc: $(srcdir)/zend-scanner.l
$(LEX) -+ -B -i -S$(srcdir)/flex.skl -Pzend -o$@ $(srcdir)/zend-scanner.l
zend-parser.h: zend-parser.c
zend-parser.c: $(srcdir)/zend-parser.y
$(YACC) -p zend -v -d $(srcdir)/zend-parser.y -o zend-parser.c
depend:
zend_execute.lo: $(srcdir)/zend_execute.c
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(INLINE_CFLAGS) -c $(srcdir)/zend_execute.c
+111
View File
@@ -0,0 +1,111 @@
Improvements
------------
Zend was designed from the ground up for increased speed,
reduced memory consumption and more reliable execution. We dare
say it meets all of these goals and does so pretty well. Beyond
that, there are several improvements in the language engine
features:
* References support. $foo = &$a; would make $foo and $a be two
names to the same variable. This works with arrays as well,
on either side; e.g., $foo = &$a[7]; would make $foo and $a[7]
be two names to the same variable. Changing one would change
the other and vice versa.
* Object overloading support. This feature allows various OO
libraries to use the OO notation of PHP to access their
functionality. Right now, no use is made of that feature,
but we'd have a COM module ready by the time PHP 4.0 is released.
A CORBA module would probably follow.
* include() and eval() are now functions, and not statements.
That means they return a value. The default return value from
include() and eval() is 1, so that you can do if (include())
without further coding. The return value may be changed by
returning a value from the global scope of the included file
or the evaluated string. For example, if 'return 7;' is executed
in the global scope of foo.inc, include("foo.inc") would evaluate
to 7.
* Automatic resource deallocation. Several people have been bitten
by the fact that PHP 3.0 had no concept of reference counting.
Zend adds full reference counting for every value in the system,
including resources. As soon as a resource is no longer referenced
from any variable, it is automatically destroyed to save memory
and resources. The most obvious example for the advantage in this
is a loop that has an SQL query inside it, something like
'$result = sql_query(...);'. In PHP 3.0, every iteration resulted
in another SQL result-set allocated in the memory, and all of the
result sets weren't destroyed until the end of the script's execution.
In Zend, as soon as we overwrite an old result set with a new one,
the old result set which is no longer referenced, is destroyed.
* Full support for nesting arrays and objects within each other, in
as many levels as you want.
* Boolean type. true and false are now constants of type boolean.
Comparing any other value to them would convert that value to a
boolean first, and conduct the comparison later. That means, for
example, that 5==true would evaluate to true (in PHP 3.0, true
was nothing but a constant for the integer value of 1, so 5==true
was identical to 5==1, which was false).
* Runtime binding of function names. This complex name has a simple
explanation - you can now call functions before they're declared!
* Added here-docs support.
* Added foreach. Two syntaxes supported:
foreach(array_expr as $val) statement
foreach(array_expr as $key => $val) statement
* A true unset() implementation. A variable or element that is unset(), is now
sent to oblivion in its entirely, no trace remains from it.
* Output buffering support! Use ob_start() to begin output buffering, ob_end_flush()
to end buffering and send out the buffered contents, ob_end_clean() to end buffering
without sending the buffered contents, and ob_get_contents() to retreive the current
contents of the output buffer.
Header information (header(), content type, cookies) are not buffered. By turning
on output buffering, you can effectively send header information all throughout your
file, regardless of whether you've emitted body output or not.
* Full variable reference within quoted strings:
${expr} - full indirect reference support for scalar variables
{variable} - full variable support
For example:
$foo[5]["bar"] = "foobar";
print "{$foo[5]["bar"]}"; // would print "foobar"
* Ability to call member functions of other classes from within member functions or from
the global scope. You can now, for example, override a parent function with a child function,
and call the parent function from it.
* Runtime information for classes (class name, parent, available functions, etc.).
* Much more efficient syntax highlighter - runs much quicker, performs more reliably, and
generates much tighter HTML.
* A full-featured debugger has been integrated with the language (supports breakpoints,
expression evaluation, step-in/over, function call backtrace, and more).
Incompatabilities
-----------------
Zend claims 100% compatability with the engine of PHP 3.0, and is
shamelessly lying about it. Here's why:
* static variable initializers only accept scalar values
(in PHP 3.0 they accepted any valid expression). The impact
should be somewhere in between void and non existent, since
initializing a static variable with anything but a simple
static value makes no sense at all.
* The scope of break and continue is local to that of an
include()'d file or an eval()'d string. The impact should
be somewhat smaller of the one above.
* return statement from a require()'d file no longer works. It
hardly worked in PHP 3.0, so the impact should be fairly small.
If you want this functionality - use include() instead.
* unset() is no longer a function, but a statement. It was never
documented as a function so the impact should be no bigger than
nada.
* The following letter combination is not supported within encapsulated
strings: "{$". If you have a string that includes this letter
combination, for example, print "{$somevar"; (which printed the
letter { and the contents of the variable $somevar in PHP 3.0),
it will result in a parse error under Zend. In this case, you
would have to change the code to print "\{$somevar";
This incompatability is due to the full variable reference
within quoted strings feature added in Zend.
+436
View File
@@ -0,0 +1,436 @@
# Microsoft Developer Studio Project File - Name="Zend" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Zend - Win32 Release_inline
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Zend.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Zend.mak" CFG="Zend - Win32 Release_inline"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Zend - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Zend - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "Zend - Win32 Release_inline" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Zend - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D ZEND_DEBUG=0 /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /D "ZEND_WIN32" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug"
# ADD RSC /l 0x40d /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug" /D "_LIB" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D ZEND_DEBUG=1 /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_Debug"
# ADD RSC /l 0x40d /d "_Debug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Zend___Win32_Release_inline"
# PROP BASE Intermediate_Dir "Zend___Win32_Release_inline"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_inline"
# PROP Intermediate_Dir "Release_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D ZEND_DEBUG=0 /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug" /D "_LIB" /D "Zend_EXPORTS" /D "LIBZEND_EXPORTS" /D "TSRM_EXPORTS" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D "WIN32" /D "_MBCS" /D "ZEND_WIN32" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug"
# ADD RSC /l 0x40d /d "NDebug"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Zend - Win32 Release"
# Name "Zend - Win32 Debug"
# Name "Zend - Win32 Release_inline"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=".\zend-parser.c"
# End Source File
# Begin Source File
SOURCE=".\zend-scanner.c"
# End Source File
# Begin Source File
SOURCE=.\zend.c
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.c
# End Source File
# Begin Source File
SOURCE=.\zend_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.c
# End Source File
# Begin Source File
SOURCE=.\zend_compile.c
# End Source File
# Begin Source File
SOURCE=.\zend_constants.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.c
# End Source File
# Begin Source File
SOURCE=.\zend_gcc_inline.c
# End Source File
# Begin Source File
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.c
# End Source File
# Begin Source File
SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_list.c
# End Source File
# Begin Source File
SOURCE=.\zend_llist.c
# End Source File
# Begin Source File
SOURCE=.\zend_opcode.c
# End Source File
# Begin Source File
SOURCE=.\zend_operators.c
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_sprintf.c
# End Source File
# Begin Source File
SOURCE=.\zend_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_variables.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\FlexLexer.h
# End Source File
# Begin Source File
SOURCE=.\modules.h
# End Source File
# Begin Source File
SOURCE=".\zend-parser.h"
# End Source File
# Begin Source File
SOURCE=".\zend-scanner.h"
# End Source File
# Begin Source File
SOURCE=.\zend.h
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.h
# End Source File
# Begin Source File
SOURCE=.\zend_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.h
# End Source File
# Begin Source File
SOURCE=.\zend_compile.h
# End Source File
# Begin Source File
SOURCE=.\zend_config.w32.h
# End Source File
# Begin Source File
SOURCE=.\zend_constants.h
# End Source File
# Begin Source File
SOURCE=.\zend_errors.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute.h
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.h
# End Source File
# Begin Source File
SOURCE=.\zend_fast_cache.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals.h
# End Source File
# Begin Source File
SOURCE=.\zend_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.h
# End Source File
# Begin Source File
SOURCE=.\zend_indent.h
# End Source File
# Begin Source File
SOURCE=.\zend_list.h
# End Source File
# Begin Source File
SOURCE=.\zend_llist.h
# End Source File
# Begin Source File
SOURCE=.\zend_operators.h
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_variables.h
# End Source File
# End Group
# Begin Group "Parsers"
# PROP Default_Filter "y"
# Begin Source File
SOURCE=".\zend-parser.y"
!IF "$(CFG)" == "Zend - Win32 Release"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Scanners"
# PROP Default_Filter "l"
# Begin Source File
SOURCE=".\zend-scanner.l"
!IF "$(CFG)" == "Zend - Win32 Release"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend-scanner.c zend-scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend-scanner.c zend-scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -i -Pzend -ozend-scanner.c zend-scanner.l
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Text Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\ZEND_BUGS
# End Source File
# Begin Source File
SOURCE=.\ZEND_CHANGES
# End Source File
# Begin Source File
SOURCE=.\ZEND_TODO
# End Source File
# End Group
# Begin Group "Resources"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\zend.ico
# End Source File
# End Group
# End Target
# End Project
+222
View File
@@ -0,0 +1,222 @@
AC_DEFUN(LIBZEND_BISON_CHECK,[
if test "$YACC" != "bison -y"; then
AC_MSG_WARN(You will need bison if you want to regenerate the Zend parser.)
else
AC_MSG_CHECKING(bison version)
set `bison --version| sed -e 's/^GNU Bison version //' -e 's/\./ /'`
if test "${1}" = "1" -a "${2}" -lt "25"; then
AC_MSG_WARN(You will need bison 1.25 if you want to regenerate the Zend parser (found ${1}.${2}).)
fi
AC_MSG_RESULT(${1}.${2} (ok))
fi
])
AC_DEFUN(LIBZEND_BASIC_CHECKS,[
AC_REQUIRE([AC_PROG_YACC])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_CC_C_O])
AC_REQUIRE([AM_PROG_LEX])
AC_REQUIRE([AC_HEADER_STDC])
LIBZEND_BISON_CHECK
dnl Ugly hack to get around a problem with gcc on AIX.
if test "$CC" = "gcc" -a "$ac_cv_prog_cc_g" = "yes" -a \
"`uname -sv`" = "AIX 4"; then
CFLAGS=`echo $CFLAGS | sed -e 's/-g//'`
fi
dnl Hack to work around a Mac OS X cpp problem
dnl Known versions needing this workaround are 5.3 and 5.4
if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
CPPFLAGS="$CPPFLAGS -traditional-cpp"
fi
AC_CHECK_HEADERS(
limits.h \
malloc.h \
string.h \
unistd.h \
stdarg.h \
sys/types.h \
signal.h \
unix.h \
dlfcn.h)
AC_TYPE_SIZE_T
AC_TYPE_SIGNAL
AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS"])
AC_CHECK_FUNC(dlopen,[AC_DEFINE(HAVE_LIBDL, 1,[ ])])
dnl This is required for QNX and may be some BSD derived systems
AC_CHECK_TYPE( uint, unsigned int )
AC_CHECK_TYPE( ulong, unsigned long )
dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_FUNC_MEMCMP
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite)
AC_ZEND_BROKEN_SPRINTF
AC_CHECK_FUNCS(finite isfinite isinf isnan)
ZEND_FP_EXCEPT
AC_SUBST(ZEND_SCANNER)
])
AC_DEFUN(LIBZEND_ENABLE_DEBUG,[
AC_ARG_ENABLE(debug,
[ --enable-debug Compile with debugging symbols],[
ZEND_DEBUG=$enableval
],[
ZEND_DEBUG=no
])
])
AC_DEFUN(LIBZEND_OTHER_CHECKS,[
AC_ARG_ENABLE(experimental-zts,
[ --enable-experimental-zts This will most likely break your build],[
ZEND_EXPERIMENTAL_ZTS=$enableval
],[
ZEND_EXPERIMENTAL_ZTS=no
])
AC_ARG_ENABLE(inline-optimization,
[ --enable-inline-optimization If you have much memory and are using
gcc, you might try this.],[
ZEND_INLINE_OPTIMIZATION=$enableval
],[
ZEND_INLINE_OPTIMIZATION=no
])
AC_ARG_ENABLE(memory-limit,
[ --enable-memory-limit Compile with memory limit support. ], [
ZEND_MEMORY_LIMIT=$enableval
],[
ZEND_MEMORY_LIMIT=no
])
AC_MSG_CHECKING(whether to enable experimental ZTS)
AC_MSG_RESULT($ZEND_EXPERIMENTAL_ZTS)
AC_MSG_CHECKING(whether to enable inline optimization for GCC)
AC_MSG_RESULT($ZEND_INLINE_OPTIMIZATION)
AC_MSG_CHECKING(whether to enable a memory limit)
AC_MSG_RESULT($ZEND_MEMORY_LIMIT)
AC_MSG_CHECKING(whether to enable Zend debugging)
AC_MSG_RESULT($ZEND_DEBUG)
if test "$ZEND_DEBUG" = "yes"; then
AC_DEFINE(ZEND_DEBUG,1,[ ])
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
if test "$CFLAGS" = "-g -O2"; then
CFLAGS=-g
fi
test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
if test "$ZEND_EXPERIMENTAL_ZTS" = "yes"; then
AC_DEFINE(ZTS,1,[ ])
ZEND_SCANNER_TYPE=cc
CPPFLAGS="$CPPFLAGS -I../TSRM"
LIBZEND_CPLUSPLUS_CHECKS
else
ZEND_SCANNER_TYPE=c
fi
ZEND_SCANNER="libZend_${ZEND_SCANNER_TYPE}.la"
if test "$ZEND_MEMORY_LIMIT" = "yes"; then
AC_DEFINE(MEMORY_LIMIT, 1, [Memory limit])
else
AC_DEFINE(MEMORY_LIMIT, 0, [Memory limit])
fi
changequote({,})
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9]*//`
else
INLINE_CFLAGS="$CFLAGS"
fi
changequote([,])
AC_C_INLINE
AC_SUBST(INLINE_CFLAGS)
])
AC_DEFUN(LIBZEND_CPLUSPLUS_CHECKS,[
dnl extra check to avoid C++ preprocessor testing if in non-ZTS mode
if test "$ZEND_EXPERIMENTAL_ZTS" = "yes"; then
AC_PROG_CXX
AC_PROG_CXXCPP
AC_LANG_CPLUSPLUS
AC_CHECK_HEADER(stdiostream.h, [ AC_DEFINE(HAVE_STDIOSTREAM_H, [], Whether you have stdiostream.h) ])
AC_CHECK_LIB(C, cin)
AC_CHECK_LIB(g++, cin)
AC_CHECK_LIB(stdc++, cin)
dnl Digital Unix 4.0
AC_CHECK_LIB(cxx, cin)
AC_CHECK_LIB(cxxstd, __array_delete)
AC_CACHE_CHECK(for class istdiostream,ac_cv_class_istdiostream,[
AC_TRY_COMPILE([
#include <sys/types.h>
#include <unistd.h>
#include <fstream.h>
#include <stdiostream.h>
],[
istdiostream *foo = new istdiostream((FILE *) 0);
],[
ac_cv_class_istdiostream=yes
],[
ac_cv_class_istdiostream=no
])
])
if test "$ac_cv_class_istdiostream" = "yes"; then
AC_DEFINE(HAVE_CLASS_ISTDIOSTREAM, 1, [Whether you have class istdiostream])
fi
AC_LANG_C
fi
])
+258
View File
@@ -0,0 +1,258 @@
# Microsoft Developer Studio Generated Dependency File, included by ZendCore.mak
.\zend_alloc.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
.\alloca.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_config.w32.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_compile.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\modules.h"\
".\zend_operators.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_API.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
".\zend_ini.h"\
.\zend_constants.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend_constants.h"\
".\zend_operators.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_execute.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_constants.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\modules.h"\
".\zend_operators.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_API.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
".\zend_ini.h"\
.\zend_highlight.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_execute.h"\
".\zend_highlight.h"\
".\zend_llist.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend-parser.tab.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
.\zend_llist.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend_llist.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_opcode.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\modules.h"\
".\zend_operators.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_API.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
".\zend_ini.h"\
.\zend_operators.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\zend_operators.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
.\zend_ptr_stack.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend_ptr_stack.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_stack.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend_stack.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_variables.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_constants.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\modules.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_API.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
".\zend_ini.h"\
".\zend_list.h"\
.\zend.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend_operators.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_API.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_compile.h"\
".\zend_config.w32.h"\
".\zend_constants.h"\
".\zend_execute.h"\
".\zend_llist.h"\
".\modules.h"\
".\zend_operators.h"\
".\zend_ptr_stack.h"\
".\zend_stack.h"\
".\zend_variables.h"\
".\zend.h"\
".\zend_API.h"\
".\zend_errors.h"\
".\zend_globals.h"\
".\zend_hash.h"\
".\zend_ini.h"\
".\zend_list.h"\
.\zend_hash.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_config.w32.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
.\zend_ini.c : \
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\zend_alloc.h"\
".\zend_config.w32.h"\
".\zend.h"\
".\zend_errors.h"\
".\zend_hash.h"\
".\zend_ini.h"\
!IF "$(CFG)" == "ZendCore - Win32 Release"
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
!ENDIF
!IF "$(CFG)" == "ZendCore - Win32 Release"
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
!ENDIF
!IF "$(CFG)" == "ZendCore - Win32 Release"
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
!ENDIF
!IF "$(CFG)" == "ZendCore - Win32 Release"
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
!ENDIF
+448
View File
@@ -0,0 +1,448 @@
# Microsoft Developer Studio Project File - Name="ZendTS" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=ZendTS - Win32 Release_TS_inline
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ZendTS.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ZendTS.mak" CFG="ZendTS - Win32 Release_TS_inline"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ZendTS - Win32 Release_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "ZendTS - Win32 Debug_TS" (based on "Win32 (x86) Static Library")
!MESSAGE "ZendTS - Win32 Release_TS_inline" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Release_TS"
# PROP BASE Intermediate_Dir "Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDebug_TS" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "Debug_TS"
# PROP BASE Intermediate_Dir "Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_Debug_TS" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "." /D "_Debug_TS" /D ZEND_DEBUG=1 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x40d /d "_Debug_TS"
# ADD RSC /l 0x40d /d "_Debug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# PROP BASE Use_MFC 0
# PROP BASE Output_Dir "ZendTS___Win32_Release_TS_inline"
# PROP BASE Intermediate_Dir "ZendTS___Win32_Release_TS_inline"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Output_Dir "Release_TS_inline"
# PROP Intermediate_Dir "Release_TS_inline"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "WIN32" /D "_MBCS" /D ZEND_DEBUG=0 /FR /FD /c
# SUBTRACT BASE CPP /YX
# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDebug_TS" /D ZEND_DEBUG=0 /D "ZEND_WIN32_FORCE_INLINE" /D _WIN32_WINNT=0x400 /D "_LIB" /D "TSRM_EXPORTS" /D "LIBZEND_EXPORTS" /D "ZTS" /D "ZEND_WIN32" /D "WIN32" /D "_MBCS" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x40d /d "NDebug_TS"
# ADD RSC /l 0x40d /d "NDebug_TS"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "ZendTS - Win32 Release_TS"
# Name "ZendTS - Win32 Debug_TS"
# Name "ZendTS - Win32 Release_TS_inline"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=".\zend-parser.c"
# End Source File
# Begin Source File
SOURCE=".\zend-scanner.cpp"
# End Source File
# Begin Source File
SOURCE=.\zend.c
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.c
# End Source File
# Begin Source File
SOURCE=.\zend_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.c
# End Source File
# Begin Source File
SOURCE=.\zend_compile.c
# End Source File
# Begin Source File
SOURCE=.\zend_constants.c
# End Source File
# Begin Source File
SOURCE=.\zend_dynamic_array.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute.c
# End Source File
# Begin Source File
SOURCE=.\zend_execute_API.c
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.c
# End Source File
# Begin Source File
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.c
# End Source File
# Begin Source File
SOURCE=.\zend_indent.c
# End Source File
# Begin Source File
SOURCE=.\zend_list.c
# End Source File
# Begin Source File
SOURCE=.\zend_llist.c
# End Source File
# Begin Source File
SOURCE=.\zend_opcode.c
# End Source File
# Begin Source File
SOURCE=.\zend_operators.c
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_sprintf.c
# End Source File
# Begin Source File
SOURCE=.\zend_stack.c
# End Source File
# Begin Source File
SOURCE=.\zend_variables.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\FlexLexer.h
# End Source File
# Begin Source File
SOURCE=.\modules.h
# End Source File
# Begin Source File
SOURCE=".\zend-parser.h"
# End Source File
# Begin Source File
SOURCE=".\zend-scanner.h"
# End Source File
# Begin Source File
SOURCE=.\zend.h
# End Source File
# Begin Source File
SOURCE=.\zend_alloc.h
# End Source File
# Begin Source File
SOURCE=.\zend_API.h
# End Source File
# Begin Source File
SOURCE=.\zend_builtin_functions.h
# End Source File
# Begin Source File
SOURCE=.\zend_compile.h
# End Source File
# Begin Source File
SOURCE=.\zend_config.w32.h
# End Source File
# Begin Source File
SOURCE=.\zend_constants.h
# End Source File
# Begin Source File
SOURCE=.\zend_dynamic_array.h
# End Source File
# Begin Source File
SOURCE=.\zend_errors.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute.h
# End Source File
# Begin Source File
SOURCE=.\zend_execute_locks.h
# End Source File
# Begin Source File
SOURCE=.\zend_extensions.h
# End Source File
# Begin Source File
SOURCE=.\zend_fast_cache.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals.h
# End Source File
# Begin Source File
SOURCE=.\zend_globals_macros.h
# End Source File
# Begin Source File
SOURCE=.\zend_hash.h
# End Source File
# Begin Source File
SOURCE=.\zend_highlight.h
# End Source File
# Begin Source File
SOURCE=.\zend_indent.h
# End Source File
# Begin Source File
SOURCE=.\zend_list.h
# End Source File
# Begin Source File
SOURCE=.\zend_llist.h
# End Source File
# Begin Source File
SOURCE=.\zend_operators.h
# End Source File
# Begin Source File
SOURCE=.\zend_ptr_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_stack.h
# End Source File
# Begin Source File
SOURCE=.\zend_variables.h
# End Source File
# End Group
# Begin Group "Parsers"
# PROP Default_Filter "y"
# Begin Source File
SOURCE=".\zend-parser.y"
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputDir=.
InputPath=".\zend-parser.y"
BuildCmds= \
if not "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "%CYGWIN%\share\bison.simple" -p zend zend-parser.y \
if "X%CYGWIN%"=="X" bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y \
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Scanners"
# PROP Default_Filter "l"
# Begin Source File
SOURCE=".\zend-scanner.l"
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -+ -B -i -Sflex.skl -Pzend -ozend-scanner.cpp zend-scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -+ -B -i -Sflex.skl -Pzend -ozend-scanner.cpp zend-scanner.l
# End Custom Build
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
# Begin Custom Build
InputPath=".\zend-scanner.l"
"zend-scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
flex -+ -B -i -Sflex.skl -Pzend -ozend-scanner.cpp zend-scanner.l
# End Custom Build
!ENDIF
# End Source File
# End Group
# Begin Group "Text Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\LICENSE
# End Source File
# Begin Source File
SOURCE=.\ZEND_BUGS
# End Source File
# Begin Source File
SOURCE=.\ZEND_CHANGES
# End Source File
# End Group
# Begin Group "Resources"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\zend.ico
# End Source File
# End Group
# End Target
# End Project
+72
View File
@@ -0,0 +1,72 @@
#define ZEND_API
#define ZEND_DLEXPORT
@TOP@
/* these are defined by automake */
#undef PACKAGE
#undef VERSION
#undef uint
#undef ulong
/* Define if you want to enable memory limit support */
#define MEMORY_LIMIT 0
@BOTTOM@
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
#endif
#if ZEND_BROKEN_SPRINTF
int zend_sprintf(char *buffer, const char *format, ...);
#else
# define zend_sprintf sprintf
#endif
#include <math.h>
#ifdef HAVE_ISNAN
#define zend_isnan(a) isnan(a)
#elif defined(NAN)
#define zend_isnan(a) (((a)==NAN)?1:0)
#else
#define zend_isnan(a) 0
#endif
#ifdef HAVE_ISINF
#define zend_isinf(a) isinf(a)
#elif defined(INFINITY)
/* Might not work, but is required by ISO C99 */
#define zend_isinf(a) (((a)==INFINITY)?1:0)
#else
#define zend_isinf(a) 0
#endif
#ifdef HAVE_FINITE
#define zend_finite(a) finite(a)
#elif defined(HAVE_ISFINITE) || defined(isfinite)
#define zend_finite(a) isfinite(a)
#elif defined(fpclassify)
#define zend_finite(a) ((fpclassify((a))!=FP_INFINITE&&fpclassify((a))!=FP_NAN)?1:0)
#else
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+47
View File
@@ -0,0 +1,47 @@
dnl $Id$
dnl
dnl This file contains local autoconf functions.
AC_DEFUN(ZEND_FP_EXCEPT,[
AC_CACHE_CHECK(whether fp_except is defined, ac_cv_type_fp_except,[
AC_TRY_COMPILE([
#include <floatingpoint.h>
],[
fp_except x = (fp_except) 0;
],[
ac_cv_type_fp_except=yes
],[
ac_cv_type_fp_except=no
],[
ac_cv_type_fp_except=no
])])
if test "$ac_cv_type_fp_except" = "yes"; then
AC_DEFINE(HAVE_FP_EXCEPT, 1, [whether floatingpoint.h defines fp_except])
fi
])
dnl
dnl Check for broken sprintf()
dnl
AC_DEFUN(AC_ZEND_BROKEN_SPRINTF,[
AC_CACHE_CHECK(whether sprintf is broken, ac_cv_broken_sprintf,[
AC_TRY_RUN([main() {char buf[20];exit(sprintf(buf,"testing 123")!=11); }],[
ac_cv_broken_sprintf=no
],[
ac_cv_broken_sprintf=yes
],[
ac_cv_broken_sprintf=no
])
])
if test "$ac_cv_broken_sprintf" = "yes"; then
ac_result=1
else
ac_result=0
fi
AC_DEFINE_UNQUOTED(ZEND_BROKEN_SPRINTF, $ac_result, [Whether sprintf is broken])
])
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
])
+43
View File
@@ -0,0 +1,43 @@
# Makefile to generate build tools
#
# Standard usage:
# make -f build.mk
#
# Written by Sascha Schumann
#
# $Id$
LT_TARGETS = ltmain.sh ltconfig
config_h_in = zend_config.h.in
makefile_am_files = Makefile.am
makefile_in_files = $(makefile_am_files:.am=.in)
makefile_files = $(makefile_am_files:e.am=e)
targets = $(makefile_in_files) $(LT_TARGETS) configure $(config_h_in)
all: $(targets)
clean:
rm -f $(targets)
$(LT_TARGETS):
rm -f $(LT_TARGETS)
libtoolize --automake $(AMFLAGS) -f
$(makefile_in_files): $(makefile_am_files)
automake -a -i $(AMFLAGS) $(makefile_files)
aclocal.m4: configure.in acinclude.m4
aclocal
$(config_h_in): configure.in acconfig.h
# explicitly remove target since autoheader does not seem to work
# correctly otherwise (timestamps are not updated)
@rm -f $@
autoheader
configure: aclocal.m4 configure.in
autoconf
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
case "$1" in
--copy)
automake_flags=--copy
shift
;;
esac
libtoolize --force --automake $automake_flags
mv aclocal.m4 aclocal.m4.old 2>/dev/null
aclocal
if cmp aclocal.m4.old aclocal.m4 > /dev/null 2>&1; then
echo "buildconf: keeping ${1}aclocal.m4"
mv aclocal.m4.old aclocal.m4
else
echo "buildconf: created or modified ${1}aclocal.m4"
fi
autoheader
automake --add-missing --include-deps $automake_flags
mv configure configure.old 2>/dev/null
autoconf
if cmp configure.old configure > /dev/null 2>&1; then
echo "buildconf: keeping ${1}configure"
mv configure.old configure
else
echo "buildconf: created or modified ${1}configure"
fi
+45
View File
@@ -0,0 +1,45 @@
dnl $Id$
dnl Process this file with autoconf to produce a configure script.
AC_INIT(zend.c)
AM_INIT_AUTOMAKE(zend, 0.80A)
AM_CONFIG_HEADER(zend_config.h)
AM_SANITY_CHECK
AM_MAINTAINER_MODE
AC_PROG_CC
AM_PROG_LEX
AM_PROG_CC_STDC
ZEND_VERSION=$VERSION
dnl We want this one before the checks, so the checks can modify CFLAGS.
test -z "$CFLAGS" && auto_cflags=1
sinclude(Zend.m4)
LIBZEND_BASIC_CHECKS
AM_PROG_LIBTOOL
if test "$enable_debug" != "yes"; then
AM_SET_LIBTOOL_VARIABLE([--silent])
fi
dnl
dnl Check for /usr/pkg/{lib,include} which is where NetBSD puts binary
dnl and source packages. This should be harmless on other OSs.
dnl
if test -d /usr/pkg/include -a -d /usr/pkg/lib ; then
CFLAGS="$CFLAGS -I/usr/pkg/include"
LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
fi
LIBZEND_ENABLE_DEBUG
LIBZEND_OTHER_CHECKS
EXTRA_LIBS="$LIBS"
LIBS=""
AC_SUBST(EXTRA_LIBS)
AC_OUTPUT(Makefile)
# Local Variables:
# tab-width: 4
# End:
+1541
View File
File diff suppressed because it is too large. Load diff
+725
View File
@@ -0,0 +1,725 @@
%{
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
/*
* LALR shift/reduce conflicts and how they are resolved:
*
* - 2 shift/reduce conflicts due to the dangeling elseif/else ambiguity. Solved by shift.
* - 1 shift/reduce conflict due to arrays within encapsulated strings. Solved by shift.
* - 1 shift/reduce conflict due to objects within encapsulated strings. Solved by shift.
*
*/
#include "zend_compile.h"
#include "zend.h"
#include "zend_list.h"
#include "zend_globals.h"
#include "zend_API.h"
#define YYERROR_VERBOSE
#define YYSTYPE znode
#ifdef ZTS
# define YYPARSE_PARAM compiler_globals
# define YYLEX_PARAM compiler_globals
#endif
%}
%pure_parser
%expect 4
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
%left ','
%left T_LOGICAL_OR
%left T_LOGICAL_XOR
%left T_LOGICAL_AND
%right T_PRINT
%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL
%left '?' ':'
%left T_BOOLEAN_OR
%left T_BOOLEAN_AND
%left '|'
%left '^'
%left '&'
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
%left T_SL T_SR
%left '+' '-' '.'
%left '*' '/' '%'
%right '!' '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
%right '['
%nonassoc T_NEW
%token T_EXIT
%token T_IF
%left T_ELSEIF
%left T_ELSE
%left T_ENDIF
%token T_LNUMBER
%token T_DNUMBER
%token T_STRING
%token T_STRING_VARNAME
%token T_VARIABLE
%token T_NUM_STRING
%token T_INLINE_HTML
%token T_CHARACTER
%token T_BAD_CHARACTER
%token T_ENCAPSED_AND_WHITESPACE
%token T_CONSTANT_ENCAPSED_STRING
%token T_ECHO
%token T_DO
%token T_WHILE
%token T_ENDWHILE
%token T_FOR
%token T_ENDFOR
%token T_FOREACH
%token T_ENDFOREACH
%token T_DECLARE
%token T_ENDDECLARE
%token T_AS
%token T_SWITCH
%token T_ENDSWITCH
%token T_CASE
%token T_DEFAULT
%token T_BREAK
%token T_CONTINUE
%token T_OLD_FUNCTION
%token T_FUNCTION
%token T_CONST
%token T_RETURN
%token T_USE
%token T_GLOBAL
%token T_STATIC
%token T_VAR
%token T_UNSET
%token T_ISSET
%token T_EMPTY
%token T_CLASS
%token T_EXTENDS
%token T_OBJECT_OPERATOR
%token T_DOUBLE_ARROW
%token T_LIST
%token T_ARRAY
%token T_LINE
%token T_FILE
%token T_COMMENT
%token T_ML_COMMENT
%token T_OPEN_TAG
%token T_OPEN_TAG_WITH_ECHO
%token T_CLOSE_TAG
%token T_WHITESPACE
%token T_START_HEREDOC
%token T_END_HEREDOC
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
%% /* Rules */
start:
top_statement_list
;
top_statement_list:
top_statement_list { do_extended_info(CLS_C); } top_statement { HANDLE_INTERACTIVE(); }
| /* empty */
;
top_statement:
statement
| declaration_statement { do_early_binding(CLS_C); }
;
inner_statement_list:
inner_statement_list { do_extended_info(CLS_C); } inner_statement { HANDLE_INTERACTIVE(); }
| /* empty */
;
inner_statement:
statement
| declaration_statement
;
statement:
unticked_statement { do_ticks(CLS_C); }
;
unticked_statement:
'{' inner_statement_list '}'
| T_IF '(' expr ')' { do_if_cond(&$3, &$4 CLS_CC); } statement { do_if_after_statement(&$4, 1 CLS_CC); } elseif_list else_single { do_if_end(CLS_C); }
| T_IF '(' expr ')' ':' { do_if_cond(&$3, &$4 CLS_CC); } inner_statement_list { do_if_after_statement(&$4, 1 CLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { do_if_end(CLS_C); }
| T_WHILE '(' { $1.u.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' { do_while_cond(&$4, &$5 CLS_CC); } while_statement { do_while_end(&$1, &$5 CLS_CC); }
| T_DO { $1.u.opline_num = get_next_op_number(CG(active_op_array)); do_do_while_begin(CLS_C); } statement T_WHILE '(' { $5.u.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' ';' { do_do_while_end(&$1, &$5, &$7 CLS_CC); }
| T_FOR
'('
for_expr
';' { do_free(&$3 CLS_CC); $4.u.opline_num = get_next_op_number(CG(active_op_array)); }
for_expr
';' { do_extended_info(CLS_C); do_for_cond(&$6, &$7 CLS_CC); }
for_expr
')' { do_free(&$9 CLS_CC); do_for_before_statement(&$4, &$7 CLS_CC); }
for_statement { do_for_end(&$7 CLS_CC); }
| T_SWITCH '(' expr ')' { do_switch_cond(&$3 CLS_CC); } switch_case_list { do_switch_end(&$6 CLS_CC); }
| T_BREAK ';' { do_brk_cont(ZEND_BRK, NULL CLS_CC); }
| T_BREAK expr ';' { do_brk_cont(ZEND_BRK, &$2 CLS_CC); }
| T_CONTINUE ';' { do_brk_cont(ZEND_CONT, NULL CLS_CC); }
| T_CONTINUE expr ';' { do_brk_cont(ZEND_CONT, &$2 CLS_CC); }
| T_RETURN ';' { do_return(NULL, 0 CLS_CC); }
| T_RETURN expr_without_variable ';' { do_return(&$2, 0 CLS_CC); }
| T_RETURN cvar ';' { do_return(&$2, 1 CLS_CC); }
| T_GLOBAL global_var_list ';'
| T_STATIC static_var_list ';'
| T_ECHO echo_expr_list ';'
| T_INLINE_HTML { do_echo(&$1 CLS_CC); }
| expr ';' { do_free(&$1 CLS_CC); }
| T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()"); zval_dtor(&$2.u.constant); }
| T_UNSET '(' unset_variables ')' ';'
| T_FOREACH '(' w_cvar T_AS { do_foreach_begin(&$1, &$3, &$2, &$4, 1 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
| T_FOREACH '(' expr_without_variable T_AS { do_foreach_begin(&$1, &$3, &$2, &$4, 0 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
| T_DECLARE { do_declare_begin(CLS_C); } '(' declare_list ')' declare_statement { do_declare_end(CLS_C); }
| ';' /* empty statement */
;
unset_variables:
unset_variable
| unset_variables ',' unset_variable
;
unset_variable:
cvar { do_end_variable_parse(BP_VAR_UNSET, 0 CLS_CC); do_unset(&$1 CLS_CC); }
;
use_filename:
T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
| '(' T_CONSTANT_ENCAPSED_STRING ')' { $$ = $2; }
;
declaration_statement:
unticked_declaration_statement { do_ticks(CLS_C); }
;
unticked_declaration_statement:
T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); }
'(' parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 0, $3.op_type CLS_CC); }
parameter_list '(' inner_statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); }
| T_CLASS T_STRING { do_begin_class_declaration(&$2, NULL CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); }
| T_CLASS T_STRING T_EXTENDS T_STRING { do_begin_class_declaration(&$2, &$4 CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); }
;
foreach_optional_arg:
/* empty */ { $$.op_type = IS_UNUSED; }
| T_DOUBLE_ARROW w_cvar { $$ = $2; }
;
for_statement:
statement
| ':' inner_statement_list T_ENDFOR ';'
;
foreach_statement:
statement
| ':' inner_statement_list T_ENDFOREACH ';'
;
declare_statement:
statement
| ':' inner_statement_list T_ENDDECLARE ';'
;
declare_list:
T_STRING '=' static_scalar { do_declare_stmt(&$1, &$3 CLS_CC); }
| declare_list ',' T_STRING '=' static_scalar { do_declare_stmt(&$3, &$5 CLS_CC); }
;
switch_case_list:
'{' case_list '}' { $$ = $2; }
| '{' ';' case_list '}' { $$ = $3; }
| ':' case_list T_ENDSWITCH ';' { $$ = $2; }
| ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; }
;
case_list:
/* empty */ { $$.op_type = IS_UNUSED; }
| case_list T_CASE expr case_separator { do_extended_info(CLS_C); do_case_before_statement(&$1, &$2, &$3 CLS_CC); } inner_statement_list { do_case_after_statement(&$$, &$2 CLS_CC); $$.op_type = IS_CONST }
| case_list T_DEFAULT case_separator { do_extended_info(CLS_C); do_default_before_statement(&$1, &$2 CLS_CC); } inner_statement_list { do_case_after_statement(&$$, &$2 CLS_CC); $$.op_type = IS_CONST; }
;
case_separator:
':'
| ';'
;
while_statement:
statement
| ':' inner_statement_list T_ENDWHILE ';'
;
elseif_list:
/* empty */
| elseif_list T_ELSEIF '(' expr ')' { do_if_cond(&$4, &$5 CLS_CC); } statement { do_if_after_statement(&$5, 0 CLS_CC); }
;
new_elseif_list:
/* empty */
| new_elseif_list T_ELSEIF '(' expr ')' ':' { do_if_cond(&$4, &$5 CLS_CC); } inner_statement_list { do_if_after_statement(&$5, 0 CLS_CC); }
;
else_single:
/* empty */
| T_ELSE statement
;
new_else_single:
/* empty */
| T_ELSE ':' inner_statement_list
;
parameter_list:
non_empty_parameter_list
| /* empty */
;
non_empty_parameter_list:
T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
| '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
| T_CONST T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
| T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$3, BYREF_NONE CLS_CC); }
| non_empty_parameter_list ',' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
| non_empty_parameter_list ',' '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
| non_empty_parameter_list ',' T_CONST T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
| non_empty_parameter_list ',' T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, BYREF_NONE CLS_CC); }
;
function_call_parameter_list:
non_empty_function_call_parameter_list { $$ = $1; }
| /* empty */ { $$.u.constant.value.lval = 0; }
;
non_empty_function_call_parameter_list:
expr_without_variable { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
| cvar { $$.u.constant.value.lval = 1; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
| '&' w_cvar { $$.u.constant.value.lval = 1; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' expr_without_variable { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
| non_empty_function_call_parameter_list ',' '&' w_cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$4, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
;
global_var_list:
global_var_list ',' global_var { do_fetch_global_or_static_variable(&$3, NULL, ZEND_FETCH_GLOBAL CLS_CC); }
| global_var { do_fetch_global_or_static_variable(&$1, NULL, ZEND_FETCH_GLOBAL CLS_CC); }
;
global_var:
T_VARIABLE { $$ = $1; }
| '$' r_cvar { $$ = $2; }
| '$' '{' expr '}' { $$ = $3; }
;
static_var_list:
static_var_list ',' T_VARIABLE { do_fetch_global_or_static_variable(&$3, NULL, ZEND_FETCH_STATIC CLS_CC); }
| static_var_list ',' T_VARIABLE '=' static_scalar { do_fetch_global_or_static_variable(&$3, &$5, ZEND_FETCH_STATIC CLS_CC); }
| T_VARIABLE { do_fetch_global_or_static_variable(&$1, NULL, ZEND_FETCH_STATIC CLS_CC); }
| T_VARIABLE '=' static_scalar { do_fetch_global_or_static_variable(&$1, &$3, ZEND_FETCH_STATIC CLS_CC); }
;
class_statement_list:
class_statement_list class_statement
| /* empty */
;
class_statement:
T_VAR class_variable_decleration ';'
| T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 1, $3.op_type CLS_CC); } '('
parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { do_begin_function_declaration(&$1, &$4, 1, $3.op_type CLS_CC); }
parameter_list '(' inner_statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); }
;
is_reference:
/* empty */ { $$.op_type = ZEND_RETURN_VAL; }
| '&' { $$.op_type = ZEND_RETURN_REF; }
class_variable_decleration:
class_variable_decleration ',' T_VARIABLE { do_declare_property(&$3, NULL CLS_CC); }
| class_variable_decleration ',' T_VARIABLE '=' static_scalar { do_declare_property(&$3, &$5 CLS_CC); }
| T_VARIABLE { do_declare_property(&$1, NULL CLS_CC); }
| T_VARIABLE '=' static_scalar { do_declare_property(&$1, &$3 CLS_CC); }
;
echo_expr_list:
| echo_expr_list ',' expr { do_echo(&$3 CLS_CC); }
| expr { do_echo(&$1 CLS_CC); }
;
for_expr:
/* empty */ { $$.op_type = IS_CONST; $$.u.constant.type = IS_BOOL; $$.u.constant.value.lval = 1; }
| non_empty_for_expr { $$ = $1; }
;
non_empty_for_expr:
non_empty_for_expr ',' { do_free(&$1 CLS_CC); } expr { $$ = $4; }
| expr { $$ = $1; }
;
expr_without_variable:
T_LIST '(' { do_list_init(CLS_C); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
| cvar '=' expr { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign(&$$, &$1, &$3 CLS_CC); }
| cvar '=' '&' w_cvar { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign_ref(&$$, &$1, &$4 CLS_CC); }
| cvar '=' '&' function_call { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); do_assign_ref(&$$, &$1, &$4 CLS_CC); }
| T_NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$1, &$2 CLS_CC); } ctor_arguments { do_end_new_object(&$$, &$2, &$1, &$4 CLS_CC); do_extended_fcall_end(CLS_C);}
| cvar T_PLUS_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
| cvar T_MINUS_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
| cvar T_MUL_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }
| cvar T_DIV_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 CLS_CC); }
| cvar T_CONCAT_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 CLS_CC); }
| cvar T_MOD_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 CLS_CC); }
| cvar T_AND_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 CLS_CC); }
| cvar T_OR_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 CLS_CC); }
| cvar T_XOR_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 CLS_CC); }
| cvar T_SL_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 CLS_CC); }
| cvar T_SR_EQUAL expr { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 CLS_CC); }
| rw_cvar T_INC { do_post_incdec(&$$, &$1, ZEND_POST_INC CLS_CC); }
| T_INC rw_cvar { do_pre_incdec(&$$, &$2, ZEND_PRE_INC CLS_CC); }
| rw_cvar T_DEC { do_post_incdec(&$$, &$1, ZEND_POST_DEC CLS_CC); }
| T_DEC rw_cvar { do_pre_incdec(&$$, &$2, ZEND_PRE_DEC CLS_CC); }
| expr T_BOOLEAN_OR { do_boolean_or_begin(&$1, &$2 CLS_CC); } expr { do_boolean_or_end(&$$, &$1, &$4, &$2 CLS_CC); }
| expr T_BOOLEAN_AND { do_boolean_and_begin(&$1, &$2 CLS_CC); } expr { do_boolean_and_end(&$$, &$1, &$4, &$2 CLS_CC); }
| expr T_LOGICAL_OR { do_boolean_or_begin(&$1, &$2 CLS_CC); } expr { do_boolean_or_end(&$$, &$1, &$4, &$2 CLS_CC); }
| expr T_LOGICAL_AND { do_boolean_and_begin(&$1, &$2 CLS_CC); } expr { do_boolean_and_end(&$$, &$1, &$4, &$2 CLS_CC); }
| expr T_LOGICAL_XOR expr { do_binary_op(ZEND_BOOL_XOR, &$$, &$1, &$3 CLS_CC); }
| expr '|' expr { do_binary_op(ZEND_BW_OR, &$$, &$1, &$3 CLS_CC); }
| expr '&' expr { do_binary_op(ZEND_BW_AND, &$$, &$1, &$3 CLS_CC); }
| expr '^' expr { do_binary_op(ZEND_BW_XOR, &$$, &$1, &$3 CLS_CC); }
| expr '.' expr { do_binary_op(ZEND_CONCAT,&$$,&$1,&$3 CLS_CC); }
| expr '+' expr { do_binary_op(ZEND_ADD,&$$,&$1,&$3 CLS_CC); }
| expr '-' expr { do_binary_op(ZEND_SUB,&$$,&$1,&$3 CLS_CC); }
| expr '*' expr { do_binary_op(ZEND_MUL,&$$,&$1,&$3 CLS_CC); }
| expr '/' expr { do_binary_op(ZEND_DIV,&$$,&$1,&$3 CLS_CC); }
| expr '%' expr { do_binary_op(ZEND_MOD,&$$,&$1,&$3 CLS_CC); }
| expr T_SL expr { do_binary_op(ZEND_SL, &$$, &$1, &$3 CLS_CC); }
| expr T_SR expr { do_binary_op(ZEND_SR, &$$, &$1, &$3 CLS_CC); }
| '+' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG; $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); do_binary_op(ZEND_ADD, &$$, &$1, &$2 CLS_CC); }
| '-' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG; $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); do_binary_op(ZEND_SUB, &$$, &$1, &$2 CLS_CC); }
| '!' expr { do_unary_op(ZEND_BOOL_NOT, &$$, &$2 CLS_CC); }
| '~' expr { do_unary_op(ZEND_BW_NOT, &$$, &$2 CLS_CC); }
| expr T_IS_IDENTICAL expr { do_binary_op(ZEND_IS_IDENTICAL, &$$, &$1, &$3 CLS_CC); }
| expr T_IS_NOT_IDENTICAL expr { do_binary_op(ZEND_IS_NOT_IDENTICAL, &$$, &$1, &$3 CLS_CC); }
| expr T_IS_EQUAL expr { do_binary_op(ZEND_IS_EQUAL, &$$, &$1, &$3 CLS_CC); }
| expr T_IS_NOT_EQUAL expr { do_binary_op(ZEND_IS_NOT_EQUAL, &$$, &$1, &$3 CLS_CC); }
| expr '<' expr { do_binary_op(ZEND_IS_SMALLER, &$$, &$1, &$3 CLS_CC); }
| expr T_IS_SMALLER_OR_EQUAL expr { do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3 CLS_CC); }
| expr '>' expr { do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 CLS_CC); }
| expr T_IS_GREATER_OR_EQUAL expr { do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 CLS_CC); }
| '(' expr ')' { $$ = $2; }
| expr '?' { do_begin_qm_op(&$1, &$2 CLS_CC); }
expr ':' { do_qm_true(&$4, &$2, &$5 CLS_CC); }
expr { do_qm_false(&$$, &$7, &$2, &$5 CLS_CC); }
| function_call { $$ = $1; }
| internal_functions_in_yacc { $$ = $1; }
| T_INT_CAST expr { do_cast(&$$, &$2, IS_LONG CLS_CC); }
| T_DOUBLE_CAST expr { do_cast(&$$, &$2, IS_DOUBLE CLS_CC); }
| T_STRING_CAST expr { do_cast(&$$, &$2, IS_STRING CLS_CC); }
| T_ARRAY_CAST expr { do_cast(&$$, &$2, IS_ARRAY CLS_CC); }
| T_OBJECT_CAST expr { do_cast(&$$, &$2, IS_OBJECT CLS_CC); }
| T_BOOL_CAST expr { do_cast(&$$, &$2, IS_BOOL CLS_CC); }
| T_UNSET_CAST expr { do_cast(&$$, &$2, IS_NULL CLS_CC); }
| T_EXIT exit_expr { do_exit(&$$, &$2 CLS_CC); }
| '@' { do_begin_silence(&$1 CLS_CC); } expr { do_end_silence(&$1 CLS_CC); $$ = $3; }
| scalar { $$ = $1; }
| T_ARRAY '(' array_pair_list ')' { $$ = $3; }
| '`' encaps_list '`' { do_shell_exec(&$$, &$2 CLS_CC); }
| T_PRINT expr { do_print(&$$, &$2 CLS_CC); }
;
function_call:
T_STRING '(' { $2.u.opline_num = do_begin_function_call(&$1 CLS_CC); }
function_call_parameter_list
')' { do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num CLS_CC); do_extended_fcall_end(CLS_C); }
| cvar '(' { do_begin_dynamic_function_call(&$1 CLS_CC); }
function_call_parameter_list
')' { do_end_function_call(&$1, &$$, &$4, 0, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
| T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_class_member_function_call(&$1, &$3 CLS_CC); }
function_call_parameter_list
')' { do_end_function_call(&$3, &$$, &$6, 1, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
;
exit_expr:
/* empty */ { memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
| '(' ')' { memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
| '(' expr ')' { $$ = $2; }
;
ctor_arguments:
/* empty */ { $$.u.constant.value.lval=0; }
| '(' function_call_parameter_list ')' { $$ = $2; }
;
class_name:
T_STRING { $$ = $1; }
| r_cvar { $$ = $1; }
;
common_scalar:
T_LNUMBER { $$ = $1; }
| T_DNUMBER { $$ = $1; }
| T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
| T_LINE { $$ = $1; }
| T_FILE { $$ = $1; }
;
static_scalar: /* compile-time evaluated scalars */
common_scalar { $$ = $1; }
| T_STRING { do_fetch_constant(&$$, &$1, ZEND_CT CLS_CC); }
| '+' static_scalar { $$ = $1; }
| '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one); $$ = $2; }
| T_ARRAY '(' static_array_pair_list ')' { $$ = $3; $$.u.constant.type = IS_CONSTANT_ARRAY; }
;
scalar:
T_STRING { do_fetch_constant(&$$, &$1, ZEND_RT CLS_CC); }
| T_STRING_VARNAME { $$ = $1; }
| common_scalar { $$ = $1; }
| '"' encaps_list '"' { $$ = $2; }
| '\'' encaps_list '\'' { $$ = $2; }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; do_end_heredoc(CLS_C); }
;
static_array_pair_list:
/* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); }
| non_empty_static_array_pair_list possible_comma { $$ = $1; }
;
possible_comma:
/* empty */
| ','
;
non_empty_static_array_pair_list:
non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW static_scalar { do_add_static_array_element(&$$, &$3, &$5); }
| non_empty_static_array_pair_list ',' static_scalar { do_add_static_array_element(&$$, NULL, &$3); }
| static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); do_add_static_array_element(&$$, &$1, &$3); }
| static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); do_add_static_array_element(&$$, NULL, &$1); }
;
expr:
r_cvar { $$ = $1; }
| expr_without_variable { $$ = $1; }
;
/*
w_expr:
w_cvar { $$ = $1; }
| expr_without_variable { $$ = $1; }
;
*/
r_cvar:
cvar { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); $$ = $1; }
;
w_cvar:
cvar { do_end_variable_parse(BP_VAR_W, 0 CLS_CC); $$ = $1; }
;
rw_cvar:
cvar { do_end_variable_parse(BP_VAR_RW, 0 CLS_CC); $$ = $1; }
;
cvar:
cvar_without_objects { $$ = $1; }
| cvar_without_objects T_OBJECT_OPERATOR { do_push_object(&$1 CLS_CC); } ref_list { $$ = $4; }
;
cvar_without_objects:
reference_variable { $$ = $1; }
| simple_indirect_reference reference_variable { do_indirect_references(&$$, &$1, &$2 CLS_CC); }
;
reference_variable:
reference_variable '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 CLS_CC); }
| reference_variable '{' expr '}' { fetch_string_offset(&$$, &$1, &$3 CLS_CC); }
| compound_variable { do_fetch_globals(&$1 CLS_CC); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
;
compound_variable:
T_VARIABLE { $$ = $1; }
| '$' '{' expr '}' { $$ = $3; }
;
dim_offset:
/* empty */ { $$.op_type = IS_UNUSED; }
| expr { $$ = $1; }
;
ref_list:
object_property { $$ = $1; }
| ref_list T_OBJECT_OPERATOR { do_push_object(&$1 CLS_CC); } object_property { $$ = $4; }
;
object_property:
object_dim_list { $$ = $1; }
| cvar_without_objects { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); } { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC);}
;
object_dim_list:
object_dim_list '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 CLS_CC); }
| object_dim_list '{' expr '}' { fetch_string_offset(&$$, &$1, &$3 CLS_CC); }
| variable_name { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC);}
;
variable_name:
T_STRING { $$ = $1; }
| '{' expr '}' { $$ = $2; }
;
simple_indirect_reference:
'$' { $$.u.constant.value.lval = 1; }
| simple_indirect_reference '$' { $$.u.constant.value.lval++; }
;
assignment_list:
assignment_list ',' assignment_list_element
| assignment_list_element
;
assignment_list_element:
cvar { do_add_list_element(&$1 CLS_CC); }
| T_LIST '(' { do_new_list_begin(CLS_C); } assignment_list ')' { do_new_list_end(CLS_C); }
| /* empty */ { do_add_list_element(NULL CLS_CC); }
;
array_pair_list:
/* empty */ { do_init_array(&$$, NULL, NULL, 0 CLS_CC); }
| non_empty_array_pair_list possible_comma { $$ = $1; }
;
non_empty_array_pair_list:
non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr { do_add_array_element(&$$, &$5, &$3, 0 CLS_CC); }
| non_empty_array_pair_list ',' expr { do_add_array_element(&$$, &$3, NULL, 0 CLS_CC); }
| expr T_DOUBLE_ARROW expr { do_init_array(&$$, &$3, &$1, 0 CLS_CC); }
| expr { do_init_array(&$$, &$1, NULL, 0 CLS_CC); }
| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_cvar { do_add_array_element(&$$, &$6, &$3, 1 CLS_CC); }
| non_empty_array_pair_list ',' '&' w_cvar { do_add_array_element(&$$, &$4, NULL, 1 CLS_CC); }
| expr T_DOUBLE_ARROW '&' w_cvar { do_init_array(&$$, &$4, &$1, 1 CLS_CC); }
| '&' w_cvar { do_init_array(&$$, &$2, NULL, 1 CLS_CC); }
;
encaps_list:
encaps_list encaps_var { do_end_variable_parse(BP_VAR_R, 0 CLS_CC); do_add_variable(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_STRING { do_add_string(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_NUM_STRING { do_add_string(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_ENCAPSED_AND_WHITESPACE { do_add_string(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_CHARACTER { do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_BAD_CHARACTER { do_add_string(&$$, &$1, &$2 CLS_CC); }
| encaps_list '[' { $2.u.constant.value.lval = (long) '['; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list ']' { $2.u.constant.value.lval = (long) ']'; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list '{' { $2.u.constant.value.lval = (long) '{'; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list '}' { $2.u.constant.value.lval = (long) '}'; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list T_OBJECT_OPERATOR { znode tmp; $2.u.constant.value.lval = (long) '-'; do_add_char(&tmp, &$1, &$2 CLS_CC); $2.u.constant.value.lval = (long) '>'; do_add_char(&$$, &tmp, &$2 CLS_CC); }
| /* empty */ { do_init_string(&$$ CLS_CC); }
;
encaps_var:
T_VARIABLE { do_fetch_globals(&$1 CLS_CC); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
| T_VARIABLE '[' { do_begin_variable_parse(CLS_C); } encaps_var_offset ']' { do_fetch_globals(&$1 CLS_CC); fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
| T_VARIABLE T_OBJECT_OPERATOR T_STRING { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$2, &$1, 1 CLS_CC); do_fetch_property(&$$, &$2, &$3 CLS_CC); }
| T_DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$2, &$4 CLS_CC); }
| T_CURLY_OPEN cvar '}' { $$ = $2; }
;
encaps_var_offset:
T_STRING { $$ = $1; }
| T_NUM_STRING { $$ = $1; }
| T_VARIABLE { fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
;
internal_functions_in_yacc:
T_ISSET '(' cvar ')' { do_isset_or_isempty(ZEND_ISSET, &$$, &$3 CLS_CC); }
| T_EMPTY '(' cvar ')' { do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 CLS_CC); }
| T_INCLUDE expr { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); }
| T_INCLUDE_ONCE expr { do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 CLS_CC); }
| T_EVAL '(' expr ')' { do_include_or_eval(ZEND_EVAL, &$$, &$3 CLS_CC); }
| T_REQUIRE expr { do_include_or_eval(ZEND_REQUIRE, &$$, &$2 CLS_CC); }
| T_REQUIRE_ONCE expr { do_include_or_eval(ZEND_REQUIRE_ONCE, &$$, &$2 CLS_CC); }
;
%%
+56
View File
@@ -0,0 +1,56 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_SCANNER_H
#define ZEND_SCANNER_H
#ifdef ZTS
class ZendFlexLexer : public yyFlexLexer
{
public:
virtual ~ZendFlexLexer();
int lex_scan(zval *zendlval CLS_DC);
void BeginState(int state);
};
#endif /* ZTS */
typedef struct _zend_lex_state {
#ifndef ZTS
YY_BUFFER_STATE buffer_state;
int state;
FILE *in;
#else
ZendFlexLexer *ZFL;
istream *input_file;
#endif
uint lineno;
char *filename;
} zend_lex_state;
void zend_fatal_scanner_error(char *);
inline void restore_lexical_state(zend_lex_state * CLS_DC);
BEGIN_EXTERN_C()
int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
END_EXTERN_C()
#endif
+1560
View File
File diff suppressed because it is too large. Load diff
+758
View File
@@ -0,0 +1,758 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_extensions.h"
#include "modules.h"
#include "zend_constants.h"
#include "zend_list.h"
#include "zend_API.h"
#include "zend_builtin_functions.h"
#ifdef ZTS
# define GLOBAL_FUNCTION_TABLE global_function_table
# define GLOBAL_CLASS_TABLE global_class_table
# define GLOBAL_CONSTANTS_TABLE global_constants_table
#else
# define GLOBAL_FUNCTION_TABLE CG(function_table)
# define GLOBAL_CLASS_TABLE CG(class_table)
# define GLOBAL_CONSTANTS_TABLE CG(zend_constants)
#endif
#if defined(ZEND_WIN32) && ZEND_DEBUG
BOOL WINAPI IsDebuggerPresent(VOID);
#endif
/* true multithread-shared globals */
ZEND_API zend_class_entry zend_standard_class_def;
ZEND_API int (*zend_printf)(const char *format, ...);
ZEND_API zend_write_func_t zend_write;
ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
ZEND_API void (*zend_block_interruptions)(void);
ZEND_API void (*zend_unblock_interruptions)(void);
ZEND_API void (*zend_ticks_function)(int ticks);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
static void (*zend_message_dispatcher_p)(long message, void *data);
static int (*zend_get_ini_entry_p)(char *name, uint name_length, zval *contents);
#ifdef ZTS
ZEND_API int compiler_globals_id;
ZEND_API int executor_globals_id;
ZEND_API int alloc_globals_id;
HashTable *global_function_table;
HashTable *global_class_table;
HashTable *global_constants_table;
#endif
zend_utility_values zend_uv;
ZEND_API zval zval_used_for_init; /* True global variable */
/* version information */
static char *zend_version_info;
static uint zend_version_info_length;
#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998-2000 Zend Technologies\n"
#define PRINT_ZVAL_INDENT 4
static void print_hash(HashTable *ht, int indent)
{
zval **tmp;
char *string_key;
unsigned long num_key;
int i;
for (i=0; i<indent; i++) {
ZEND_PUTS(" ");
}
ZEND_PUTS("(\n");
indent += PRINT_ZVAL_INDENT;
zend_hash_internal_pointer_reset(ht);
while (zend_hash_get_current_data(ht, (void **) &tmp) == SUCCESS) {
for (i=0; i<indent; i++) {
ZEND_PUTS(" ");
}
ZEND_PUTS("[");
switch (zend_hash_get_current_key(ht, &string_key, &num_key)) {
case HASH_KEY_IS_STRING:
ZEND_PUTS(string_key);
efree(string_key);
break;
case HASH_KEY_IS_LONG:
zend_printf("%ld",num_key);
break;
}
ZEND_PUTS("] => ");
zend_print_zval_r(*tmp, indent+PRINT_ZVAL_INDENT);
ZEND_PUTS("\n");
zend_hash_move_forward(ht);
}
indent -= PRINT_ZVAL_INDENT;
for (i=0; i<indent; i++) {
ZEND_PUTS(" ");
}
ZEND_PUTS(")\n");
}
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
{
if (expr->type==IS_STRING) {
*use_copy = 0;
return;
}
switch (expr->type) {
case IS_NULL:
expr_copy->value.str.len = 0;
expr_copy->value.str.val = empty_string;
break;
case IS_BOOL:
if (expr->value.lval) {
expr_copy->value.str.len = 1;
expr_copy->value.str.val = estrndup("1", 1);
} else {
expr_copy->value.str.len = 0;
expr_copy->value.str.val = empty_string;
}
break;
case IS_RESOURCE:
expr_copy->value.str.val = (char *) emalloc(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG);
expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Resource id #%ld", expr->value.lval);
break;
case IS_ARRAY:
expr_copy->value.str.len = sizeof("Array")-1;
expr_copy->value.str.val = estrndup("Array", expr_copy->value.str.len);
break;
case IS_OBJECT:
expr_copy->value.str.len = sizeof("Object")-1;
expr_copy->value.str.val = estrndup("Object", expr_copy->value.str.len);
break;
default:
*expr_copy = *expr;
zval_copy_ctor(expr_copy);
convert_to_string(expr_copy);
break;
}
expr_copy->type = IS_STRING;
*use_copy = 1;
}
ZEND_API int zend_print_zval(zval *expr, int indent)
{
return zend_print_zval_ex(zend_write, expr, indent);
}
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent)
{
zval expr_copy;
int use_copy;
zend_make_printable_zval(expr, &expr_copy, &use_copy);
if (use_copy) {
expr = &expr_copy;
}
if (expr->value.str.len==0) { /* optimize away empty strings */
if (use_copy) {
zval_dtor(expr);
}
return 0;
}
write_func(expr->value.str.val,expr->value.str.len);
if (use_copy) {
zval_dtor(expr);
}
return expr->value.str.len;
}
ZEND_API void zend_print_zval_r(zval *expr, int indent)
{
zend_print_zval_r_ex(zend_write, expr, indent);
}
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent)
{
switch(expr->type) {
case IS_ARRAY:
ZEND_PUTS("Array\n");
print_hash(expr->value.ht,indent);
break;
case IS_OBJECT:
zend_printf("%s Object\n", expr->value.obj.ce->name);
print_hash(expr->value.obj.properties, indent);
break;
default:
zend_print_variable(expr);
break;
}
}
static FILE *zend_fopen_wrapper(const char *filename, char **opened_path)
{
if (opened_path) {
*opened_path = estrdup(filename);
}
return fopen(filename, "rb");
}
static void register_standard_class(void)
{
zend_standard_class_def.type = ZEND_INTERNAL_CLASS;
zend_standard_class_def.name_length = sizeof("stdClass") - 1;
zend_standard_class_def.name = zend_strndup("stdClass", zend_standard_class_def.name_length);
zend_standard_class_def.parent = NULL;
zend_hash_init_ex(&zend_standard_class_def.default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
zend_hash_init_ex(&zend_standard_class_def.function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_standard_class_def.handle_function_call = NULL;
zend_standard_class_def.handle_property_get = NULL;
zend_standard_class_def.handle_property_set = NULL;
zend_standard_class_def.refcount = (int *) malloc(sizeof(int));
*zend_standard_class_def.refcount = 1;
zend_hash_add(GLOBAL_CLASS_TABLE, "stdclass", sizeof("stdclass"), &zend_standard_class_def, sizeof(zend_class_entry), NULL);
}
static void zend_set_default_compile_time_values(CLS_D)
{
/* default compile-time values */
CG(asp_tags) = 0;
CG(short_tags) = 1;
CG(allow_call_time_pass_reference) = 1;
CG(extended_info) = 0;
}
#ifdef ZTS
static void compiler_globals_ctor(zend_compiler_globals *compiler_globals)
{
zend_function tmp_func;
zend_class_entry tmp_class;
compiler_globals->compiled_filename = NULL;
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
zend_hash_copy(compiler_globals->class_table, global_class_table, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry));
zend_set_default_compile_time_values(CLS_C);
}
static void compiler_globals_dtor(zend_compiler_globals *compiler_globals)
{
if (compiler_globals->function_table != global_function_table) {
zend_hash_destroy(compiler_globals->function_table);
free(compiler_globals->function_table);
}
if (compiler_globals->class_table != global_class_table) {
zend_hash_destroy(compiler_globals->class_table);
free(compiler_globals->class_table);
}
}
static void executor_globals_ctor(zend_executor_globals *executor_globals)
{
if (global_constants_table) {
zend_startup_constants(ELS_C);
zend_copy_constants(executor_globals->zend_constants, global_constants_table);
}
zend_init_rsrc_plist(ELS_C);
EG(lambda_count)=0;
}
static void executor_globals_dtor(zend_executor_globals *executor_globals)
{
zend_shutdown_constants(ELS_C);
zend_destroy_rsrc_plist(ELS_C);
}
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
{
start_memory_manager(ALS_C);
}
#endif
#ifdef __FreeBSD__
/* FreeBSD floating point precision fix */
#include <floatingpoint.h>
#endif
int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions)
{
#ifdef ZTS
zend_compiler_globals *compiler_globals;
zend_executor_globals *executor_globals;
alloc_globals_id = ts_allocate_id(sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, NULL);
#else
start_memory_manager(ALS_C);
#endif
#ifdef __FreeBSD__
{
/* FreeBSD floating point precision fix */
#ifdef HAVE_FP_EXCEPT
fp_except
#else
fp_except_t
#endif
mask;
mask = fpgetmask();
fpsetmask(mask & ~FP_X_IMP);
}
#endif
zend_startup_extensions_mechanism();
/* Set up utility functions and values */
zend_error_cb = utility_functions->error_function;
zend_printf = utility_functions->printf_function;
zend_write = (zend_write_func_t) utility_functions->write_function;
zend_fopen = utility_functions->fopen_function;
if (!zend_fopen) {
zend_fopen = zend_fopen_wrapper;
}
zend_message_dispatcher_p = utility_functions->message_handler;
zend_block_interruptions = utility_functions->block_interruptions;
zend_unblock_interruptions = utility_functions->unblock_interruptions;
zend_get_ini_entry_p = utility_functions->get_ini_entry;
zend_ticks_function = utility_functions->ticks_function;
zend_compile_file = compile_file;
zend_execute = execute;
/* set up version */
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO)-1;
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
register_standard_class();
zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
zend_init_rsrc_list_dtors();
/* This zval can be used to initialize allocate zval's to an uninit'ed value */
zval_used_for_init.is_ref = 0;
zval_used_for_init.refcount = 1;
zval_used_for_init.type = IS_NULL;
#ifdef ZTS
global_constants_table = NULL;
compiler_globals_id = ts_allocate_id(sizeof(zend_compiler_globals), (void (*)(void *)) compiler_globals_ctor, (void (*)(void *)) compiler_globals_dtor);
executor_globals_id = ts_allocate_id(sizeof(zend_executor_globals), (void (*)(void *)) executor_globals_ctor, (void (*)(void *)) executor_globals_dtor);
compiler_globals = ts_resource(compiler_globals_id);
executor_globals = ts_resource(executor_globals_id);
compiler_globals_dtor(compiler_globals);
compiler_globals->function_table = GLOBAL_FUNCTION_TABLE;
compiler_globals->class_table = GLOBAL_CLASS_TABLE;
zend_startup_constants(executor_globals);
GLOBAL_CONSTANTS_TABLE = EG(zend_constants);
#else
zend_startup_constants();
zend_set_default_compile_time_values(CLS_C);
#endif
zend_register_standard_constants(ELS_C);
#ifndef ZTS
zend_init_rsrc_plist(ELS_C);
#endif
if (start_builtin_functions) {
zend_startup_builtin_functions();
}
return SUCCESS;
}
void zend_shutdown()
{
#ifdef ZEND_WIN32
zend_shutdown_timeout_thread();
#endif
#ifndef ZTS
zend_destroy_rsrc_plist();
#endif
zend_destroy_rsrc_list_dtors();
zend_hash_destroy(&module_registry);
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
free(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
free(GLOBAL_CLASS_TABLE);
zend_shutdown_extensions();
free(zend_version_info);
#ifndef ZTS
zend_shutdown_constants();
#endif
}
void zend_set_utility_values(zend_utility_values *utility_values)
{
zend_uv = *utility_values;
zend_uv.import_use_extension_length = strlen(zend_uv.import_use_extension);
}
/* this should be compatible with the standard zenderror */
void zenderror(char *error)
{
zend_error(E_PARSE, error);
}
BEGIN_EXTERN_C()
ZEND_API void zend_bailout()
{
CLS_FETCH();
ELS_FETCH();
CG(unclean_shutdown) = 1;
longjmp(EG(bailout), FAILURE);
}
END_EXTERN_C()
void zend_append_version_info(zend_extension *extension)
{
char *new_info;
uint new_info_length;
new_info_length = sizeof(" with v, by \n")
+ strlen(extension->name)
+ strlen(extension->version)
+ strlen(extension->copyright)
+ strlen(extension->author);
new_info = (char *) malloc(new_info_length+1);
sprintf(new_info, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length+1);
strcat(zend_version_info, new_info);
zend_version_info_length += new_info_length;
free(new_info);
}
ZEND_API char *get_zend_version()
{
return zend_version_info;
}
void zend_activate(CLS_D ELS_DC)
{
init_compiler(CLS_C ELS_CC);
init_executor(CLS_C ELS_CC);
startup_scanner(CLS_C);
}
void zend_activate_modules()
{
zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_request_startup);
}
void zend_deactivate_modules()
{
ELS_FETCH();
EG(opline_ptr) = NULL; /* we're no longer executing anything */
if (setjmp(EG(bailout))==0) {
zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_cleanup);
}
}
void zend_deactivate(CLS_D ELS_DC)
{
/* we're no longer executing anything */
EG(opline_ptr) = NULL;
EG(active_symbol_table) = NULL;
if (setjmp(EG(bailout))==0) {
shutdown_scanner(CLS_C);
}
if (setjmp(EG(bailout))==0) {
shutdown_executor(ELS_C);
}
if (setjmp(EG(bailout))==0) {
shutdown_compiler(CLS_C);
}
}
BEGIN_EXTERN_C()
ZEND_API void zend_message_dispatcher(long message, void *data)
{
if (zend_message_dispatcher_p) {
zend_message_dispatcher_p(message, data);
}
}
END_EXTERN_C()
ZEND_API int zend_get_ini_entry(char *name, uint name_length, zval *contents)
{
if (zend_get_ini_entry_p) {
return zend_get_ini_entry_p(name, name_length, contents);
} else {
return FAILURE;
}
}
#define ZEND_ERROR_BUFFER_SIZE 1024
ZEND_API void zend_error(int type, const char *format, ...)
{
va_list args;
zval ***params;
zval *retval;
zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
char *error_filename;
uint error_lineno;
zval *orig_user_error_handler;
ELS_FETCH();
CLS_FETCH();
/* Obtain relevant filename and lineno */
switch (type) {
case E_CORE_ERROR:
case E_CORE_WARNING:
error_filename = NULL;
error_lineno = 0;
break;
case E_PARSE:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
case E_ERROR:
case E_NOTICE:
case E_WARNING:
case E_USER_ERROR:
case E_USER_WARNING:
case E_USER_NOTICE:
if (zend_is_compiling()) {
error_filename = zend_get_compiled_filename(CLS_C);
error_lineno = zend_get_compiled_lineno(CLS_C);
} else if (zend_is_executing()) {
error_filename = zend_get_executed_filename(ELS_C);
error_lineno = zend_get_executed_lineno(ELS_C);
} else {
error_filename = NULL;
error_lineno = 0;
}
break;
default:
error_filename = NULL;
error_lineno = 0;
break;
}
if (!error_filename) {
error_filename = "Unknown";
}
va_start(args, format);
/* if we don't have a user defined error handler */
if (!EG(user_error_handler)) {
zend_error_cb(type, error_filename, error_lineno, format, args);
} else switch (type) {
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
/* The error may not be safe to handle in user-space */
zend_error_cb(type, error_filename, error_lineno, format, args);
break;
default:
/* Handle the error in user space */
ALLOC_INIT_ZVAL(z_error_message);
ALLOC_INIT_ZVAL(z_error_type);
ALLOC_INIT_ZVAL(z_error_filename);
ALLOC_INIT_ZVAL(z_error_lineno);
ALLOC_INIT_ZVAL(z_context);
z_error_message->value.str.val = (char *) emalloc(ZEND_ERROR_BUFFER_SIZE);
#ifdef HAVE_VSNPRINTF
z_error_message->value.str.len = vsnprintf(z_error_message->value.str.val, ZEND_ERROR_BUFFER_SIZE, format, args);
if (z_error_message->value.str.len > ZEND_ERROR_BUFFER_SIZE-1) {
z_error_message->value.str.len = ZEND_ERROR_BUFFER_SIZE-1;
}
#else
strncpy(z_error_message->value.str.val, format, ZEND_ERROR_BUFFER_SIZE);
/* This is risky... */
/* z_error_message->value.str.len = vsprintf(z_error_message->value.str.val, format, args); */
#endif
z_error_message->type = IS_STRING;
z_error_type->value.lval = type;
z_error_type->type = IS_LONG;
if (error_filename) {
z_error_filename->value.str.len = strlen(error_filename);
z_error_filename->value.str.val = estrndup(error_filename, z_error_filename->value.str.len);
z_error_filename->type = IS_STRING;
}
z_error_lineno->value.lval = error_lineno;
z_error_lineno->type = IS_LONG;
z_context->value.ht = EG(active_symbol_table);
z_context->type = IS_ARRAY;
ZVAL_ADDREF(z_context); /* we don't want this one to be freed */
params = (zval ***) emalloc(sizeof(zval **)*5);
params[0] = &z_error_type;
params[1] = &z_error_message;
params[2] = &z_error_filename;
params[3] = &z_error_lineno;
params[4] = &z_context;
orig_user_error_handler = EG(user_error_handler);
EG(user_error_handler) = NULL;
if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL)==SUCCESS) {
zval_ptr_dtor(&retval);
} else {
/* The user error handler failed, use built-in error handler */
zend_error_cb(type, error_filename, error_lineno, format, args);
}
EG(user_error_handler) = orig_user_error_handler;
efree(params);
zval_ptr_dtor(&z_error_message);
zval_ptr_dtor(&z_error_type);
zval_ptr_dtor(&z_error_filename);
zval_ptr_dtor(&z_error_lineno);
if (ZVAL_REFCOUNT(z_context)==2) {
FREE_ZVAL(z_context);
}
break;
}
va_end(args);
}
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...)
{
#if ZEND_DEBUG
va_list args;
va_start(args, format);
# ifdef ZEND_WIN32
{
char output_buf[1024];
vsnprintf(output_buf, 1024, format, args);
OutputDebugString(output_buf);
OutputDebugString("\n");
if (trigger_break && IsDebuggerPresent()) {
DebugBreak();
}
}
# else
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
# endif
va_end(args);
#endif
}
ZEND_API int zend_execute_scripts(int type CLS_DC ELS_DC, int file_count, ...)
{
va_list files;
int i;
zend_file_handle *file_handle;
va_start(files, file_count);
for (i=0; i<file_count; i++) {
file_handle = va_arg(files, zend_file_handle *);
if (!file_handle) {
continue;
}
EG(active_op_array) = zend_compile_file(file_handle, ZEND_INCLUDE CLS_CC);
zend_destroy_file_handle(file_handle CLS_CC);
if (EG(active_op_array)) {
zend_execute(EG(active_op_array) ELS_CC);
zval_ptr_dtor(EG(return_value_ptr_ptr));
EG(return_value_ptr_ptr) = &EG(global_return_value_ptr);
EG(global_return_value_ptr) = NULL;
destroy_op_array(EG(active_op_array));
efree(EG(active_op_array));
} else if (type==ZEND_REQUIRE) {
va_end(files);
return FAILURE;
}
}
va_end(files);
return SUCCESS;
}
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
ZEND_API char *zend_make_compiled_string_description(char *name)
{
char *cur_filename;
int cur_lineno;
char *compiled_string_description;
CLS_FETCH();
ELS_FETCH();
if (zend_is_compiling()) {
cur_filename = zend_get_compiled_filename(CLS_C);
cur_lineno = zend_get_compiled_lineno(CLS_C);
} else if (zend_is_executing()) {
cur_filename = zend_get_executed_filename(ELS_C);
cur_lineno = zend_get_executed_lineno(ELS_C);
} else {
cur_filename = "Unknown";
cur_lineno = 0;
}
compiled_string_description = emalloc(sizeof(COMPILED_STRING_DESCRIPTION_FORMAT)+strlen(name)+strlen(cur_filename)+MAX_LENGTH_OF_LONG);
sprintf(compiled_string_description, COMPILED_STRING_DESCRIPTION_FORMAT, cur_filename, cur_lineno, name);
return compiled_string_description;
}
+444
View File
@@ -0,0 +1,444 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_H
#define ZEND_H
#define ZEND_VERSION "1.0.3"
#ifdef __cplusplus
#define BEGIN_EXTERN_C() extern "C" {
#define END_EXTERN_C() }
#else
#define BEGIN_EXTERN_C()
#define END_EXTERN_C()
#endif
#include <stdio.h>
/*
* general definitions
*/
#ifdef ZEND_WIN32
# include "zend_config.w32.h"
#else
# include "zend_config.h"
#endif
/* all HAVE_XXX test have to be after the include of zend_config above */
#ifdef HAVE_UNIX_H
# include <unix.h>
#endif
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#if defined(HAVE_LIBDL)
# ifndef RTLD_LAZY
# define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */
# endif
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
# define DL_UNLOAD dlclose
# define DL_FETCH_SYMBOL dlsym
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 1
#elif defined(ZEND_WIN32)
# define DL_LOAD(libname) LoadLibrary(libname)
# define DL_FETCH_SYMBOL GetProcAddress
# define DL_UNLOAD FreeLibrary
# define DL_HANDLE HMODULE
# define ZEND_EXTENSIONS_SUPPORT 1
#else
# define DL_HANDLE void *
# define ZEND_EXTENSIONS_SUPPORT 0
#endif
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32))
# define do_alloca(p) alloca(p)
# define free_alloca(p)
#else
# define do_alloca(p) emalloc(p)
# define free_alloca(p) efree(p)
#endif
#if ZEND_DEBUG
#define ZEND_FILE_LINE_D char *__zend_filename, uint __zend_lineno
#define ZEND_FILE_LINE_DC , ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_ORIG_D char *__zend_orig_filename, uint __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_DC , ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_RELAY_C __zend_filename, __zend_lineno
#define ZEND_FILE_LINE_RELAY_CC , ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_C __FILE__, __LINE__
#define ZEND_FILE_LINE_CC , ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_EMPTY_C NULL, 0
#define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C
#else
#define ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_DC
#define ZEND_FILE_LINE_ORIG_D
#define ZEND_FILE_LINE_ORIG_DC
#define ZEND_FILE_LINE_RELAY_C
#define ZEND_FILE_LINE_RELAY_CC
#define ZEND_FILE_LINE_C
#define ZEND_FILE_LINE_CC
#define ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_EMPTY_CC
#define ZEND_FILE_LINE_ORIG_RELAY_C
#define ZEND_FILE_LINE_ORIG_RELAY_CC
#endif /* ZEND_DEBUG */
#ifdef ZTS
#define ZTS_V 1
#else
#define ZTS_V 0
#endif
#include "zend_errors.h"
#include "zend_alloc.h"
typedef unsigned char zend_bool;
typedef unsigned char zend_uchar;
typedef unsigned int zend_uint;
typedef unsigned long zend_ulong;
typedef unsigned short zend_ushort;
#undef SUCCESS
#undef FAILURE
#define SUCCESS 0
#define FAILURE -1 /* this MUST stay a negative number, or it may affect functions! */
#include "zend_hash.h"
#include "zend_llist.h"
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval *this_ptr, int return_value_used ELS_DC
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, this_ptr, return_value_used ELS_CC
/*
* zval
*/
typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
struct {
zend_class_entry *ce;
HashTable *properties;
} obj;
} zvalue_value;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uchar type; /* active type */
zend_uchar is_ref;
zend_ushort refcount;
};
typedef struct _zend_function_entry {
char *fname;
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
unsigned char *func_arg_types;
} zend_function_entry;
typedef struct _zend_property_reference {
int type; /* read, write or r/w */
zval *object;
zend_llist *elements_list;
} zend_property_reference;
typedef struct _zend_overloaded_element {
int type; /* array offset or object proprety */
zval element;
} zend_overloaded_element;
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
struct _zend_class_entry {
char type;
char *name;
uint name_length;
struct _zend_class_entry *parent;
int *refcount;
zend_bool constants_updated;
HashTable function_table;
HashTable default_properties;
zend_function_entry *builtin_functions;
/* handlers */
void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
zval (*handle_property_get)(zend_property_reference *property_reference);
int (*handle_property_set)(zend_property_reference *property_reference, zval *value);
};
typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
int (*printf_function)(const char *format, ...);
int (*write_function)(const char *str, uint str_length);
FILE *(*fopen_function)(const char *filename, char **opened_path);
void (*message_handler)(long message, void *data);
void (*block_interruptions)(void);
void (*unblock_interruptions)(void);
int (*get_ini_entry)(char *name, uint name_length, zval *contents);
void (*ticks_function)(int ticks);
} zend_utility_functions;
typedef struct _zend_utility_values {
char *import_use_extension;
uint import_use_extension_length;
} zend_utility_values;
typedef int (*zend_write_func_t)(const char *str, uint str_length);
#undef MIN
#undef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define ZEND_STRL(str) (str), (sizeof(str)-1)
#define ZEND_STRS(str) (str), (sizeof(str)
#define ZEND_NORMALIZE_BOOL(n) \
((n) ? (((n)>0) ? 1 : -1) : 0)
/* data types */
#define IS_NULL 0
#define IS_LONG 1
#define IS_DOUBLE 2
#define IS_STRING 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_BOOL 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
/* Special data type to temporarily mark large numbers */
#define FLAG_IS_BC 10 /* for parser internal use only */
/* overloaded elements data types */
#define OE_IS_ARRAY (1<<0)
#define OE_IS_OBJECT (1<<1)
#define OE_IS_METHOD (1<<2)
/* Argument passing types */
#define BYREF_NONE 0
#define BYREF_FORCE 1
#define BYREF_ALLOW 2
#define BYREF_FORCE_REST 3
int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions);
void zend_shutdown(void);
void zend_set_utility_values(zend_utility_values *utility_values);
BEGIN_EXTERN_C()
ZEND_API void zend_bailout(void);
END_EXTERN_C()
ZEND_API char *get_zend_version(void);
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
ZEND_API int zend_print_zval(zval *expr, int indent);
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
ZEND_API void zend_print_zval_r(zval *expr, int indent);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent);
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...);
#if ZEND_DEBUG
#define Z_DBG(expr) (expr)
#else
#define Z_DBG(expr)
#endif
ZEND_API extern char *empty_string;
#define STR_FREE(ptr) if (ptr && ptr!=empty_string) { efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr && ptr!=empty_string) { efree_rel(ptr); }
#define STR_REALLOC(ptr, size) \
if (ptr!=empty_string) { \
ptr = (char *) erealloc(ptr, size); \
} else { \
ptr = (char *) emalloc(size); \
memset(ptr, 0, size); \
}
/* output support */
#define ZEND_WRITE(str, str_len) zend_write((str), (str_len))
#define ZEND_PUTS(str) zend_write((str), strlen((str)))
#define ZEND_PUTC(c) zend_write(&(c), 1), (c)
BEGIN_EXTERN_C()
extern ZEND_API int (*zend_printf)(const char *format, ...);
extern ZEND_API zend_write_func_t zend_write;
extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
extern ZEND_API void (*zend_block_interruptions)(void);
extern ZEND_API void (*zend_unblock_interruptions)(void);
extern ZEND_API void (*zend_ticks_function)(int ticks);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
ZEND_API void zend_error(int type, const char *format, ...);
void zenderror(char *error);
extern ZEND_API zend_class_entry zend_standard_class_def;
extern zend_utility_values zend_uv;
extern ZEND_API zval zval_used_for_init;
END_EXTERN_C()
#define ZEND_UV(name) (zend_uv.name)
#define HANDLE_BLOCK_INTERRUPTIONS() if (zend_block_interruptions) { zend_block_interruptions(); }
#define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
BEGIN_EXTERN_C()
ZEND_API void zend_message_dispatcher(long message, void *data);
END_EXTERN_C()
ZEND_API int zend_get_ini_entry(char *name, uint name_length, zval *contents);
/* Messages for applications of Zend */
#define ZMSG_FAILED_INCLUDE_FOPEN 1L
#define ZMSG_FAILED_REQUIRE_FOPEN 2L
#define ZMSG_FAILED_HIGHLIGHT_FOPEN 3L
#define ZMSG_MEMORY_LEAK_DETECTED 4L
#define ZMSG_MEMORY_LEAK_REPEATED 5L
#define ZMSG_LOG_SCRIPT_NAME 6L
#define ZVAL_ADDREF(pz) (++(pz)->refcount)
#define ZVAL_DELREF(pz) (--(pz)->refcount)
#define ZVAL_REFCOUNT(pz) ((pz)->refcount)
#define INIT_PZVAL(z) \
(z)->refcount = 1; \
(z)->is_ref = 0;
#define INIT_ZVAL(z) z = zval_used_for_init;
#define ALLOC_INIT_ZVAL(zp) \
ALLOC_ZVAL(zp); \
INIT_ZVAL(*zp);
#define MAKE_STD_ZVAL(zv) \
ALLOC_ZVAL(zv); \
INIT_PZVAL(zv);
#define PZVAL_IS_REF(z) ((z)->is_ref)
#define SEPARATE_ZVAL(ppzv) \
{ \
zval *orig_ptr = *(ppzv); \
\
if (orig_ptr->refcount>1) { \
orig_ptr->refcount--; \
ALLOC_ZVAL(*(ppzv)); \
**(ppzv) = *orig_ptr; \
zval_copy_ctor(*(ppzv)); \
(*(ppzv))->refcount=1; \
(*(ppzv))->is_ref = 0; \
} \
}
#define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \
if (!PZVAL_IS_REF(*ppzv)) { \
SEPARATE_ZVAL(ppzv); \
}
#define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \
if (!PZVAL_IS_REF(*ppzv)) { \
SEPARATE_ZVAL(ppzv); \
(*(ppzv))->is_ref = 1; \
}
#define COPY_PZVAL_TO_ZVAL(zv, pzv) \
(zv) = *(pzv); \
if ((pzv)->refcount>1) { \
zval_copy_ctor(&(zv)); \
(pzv)->refcount--; \
} else { \
FREE_ZVAL(pzv); \
} \
INIT_PZVAL(&(zv));
#define ZEND_MAX_RESERVED_RESOURCES 2
#ifdef ZEND_WIN32
/* Only use this macro if you know for sure that all of the switches values
are covered by its case statements */
#define EMPTY_SWITCH_DEFAULT_CASE() \
default: \
__assume(0); \
break;
#else
#define EMPTY_SWITCH_DEFAULT_CASE()
#endif
#endif /* ZEND_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+984
View File
@@ -0,0 +1,984 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_execute.h"
#include "zend_API.h"
#include "modules.h"
#include "zend_constants.h"
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
/* these variables are true statics/globals, and have to be mutex'ed on every access */
static int module_count=0;
HashTable module_registry;
/* this function doesn't check for too many parameters */
ZEND_API int zend_get_parameters(int ht, int param_count, ...)
{
void **p;
int arg_count;
va_list ptr;
zval **param, *param_ptr;
ELS_FETCH();
p = EG(argument_stack).top_element-2;
arg_count = (ulong) *p;
if (param_count>arg_count) {
return FAILURE;
}
va_start(ptr, param_count);
while (param_count-->0) {
param = va_arg(ptr, zval **);
param_ptr = *(p-arg_count);
if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) {
zval *new_tmp;
ALLOC_ZVAL(new_tmp);
*new_tmp = *param_ptr;
zval_copy_ctor(new_tmp);
INIT_PZVAL(new_tmp);
param_ptr = new_tmp;
((zval *) *(p-arg_count))->refcount--;
*(p-arg_count) = param_ptr;
}
*param = param_ptr;
arg_count--;
}
va_end(ptr);
return SUCCESS;
}
ZEND_API int zend_get_parameters_array(int ht, int param_count, zval **argument_array)
{
void **p;
int arg_count;
zval *param_ptr;
ELS_FETCH();
p = EG(argument_stack).top_element-2;
arg_count = (ulong) *p;
if (param_count>arg_count) {
return FAILURE;
}
while (param_count-->0) {
param_ptr = *(p-arg_count);
if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) {
zval *new_tmp;
ALLOC_ZVAL(new_tmp);
*new_tmp = *param_ptr;
zval_copy_ctor(new_tmp);
INIT_PZVAL(new_tmp);
param_ptr = new_tmp;
((zval *) *(p-arg_count))->refcount--;
*(p-arg_count) = param_ptr;
}
*(argument_array++) = param_ptr;
arg_count--;
}
return SUCCESS;
}
/* Zend-optimized Extended functions */
/* this function doesn't check for too many parameters */
ZEND_API int zend_get_parameters_ex(int param_count, ...)
{
void **p;
int arg_count;
va_list ptr;
zval ***param;
ELS_FETCH();
p = EG(argument_stack).top_element-2;
arg_count = (ulong) *p;
if (param_count>arg_count) {
return FAILURE;
}
va_start(ptr, param_count);
while (param_count-->0) {
param = va_arg(ptr, zval ***);
*param = (zval **) p-(arg_count--);
}
va_end(ptr);
return SUCCESS;
}
ZEND_API int zend_get_parameters_array_ex(int param_count, zval ***argument_array)
{
void **p;
int arg_count;
ELS_FETCH();
p = EG(argument_stack).top_element-2;
arg_count = (ulong) *p;
if (param_count>arg_count) {
return FAILURE;
}
while (param_count-->0) {
*(argument_array++) = (zval **) p-(arg_count--);
}
return SUCCESS;
}
ZEND_API int ParameterPassedByReference(int ht, uint n)
{
void **p;
ulong arg_count;
zval *arg;
ELS_FETCH();
p = EG(argument_stack).elements+EG(argument_stack).top-2;
arg_count = (ulong) *p;
if (n>arg_count) {
return FAILURE;
}
arg = (zval *) *(p-arg_count+n-1);
return PZVAL_IS_REF(arg);
}
ZEND_API void wrong_param_count()
{
zend_error(E_WARNING,"Wrong parameter count for %s()",get_active_function_name());
}
ZEND_API inline int _array_init(zval *arg ZEND_FILE_LINE_DC)
{
ALLOC_HASHTABLE_REL(arg->value.ht);
if (!arg->value.ht || zend_hash_init(arg->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0)) {
zend_error(E_ERROR, "Cannot allocate memory for array");
return FAILURE;
}
arg->type = IS_ARRAY;
return SUCCESS;
}
ZEND_API inline int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC)
{
zval *tmp;
if (!class_type->constants_updated) {
zend_hash_apply_with_argument(&class_type->default_properties, (int (*)(void *,void *)) zval_update_constant, (void *) 1);
class_type->constants_updated = 1;
}
ALLOC_HASHTABLE_REL(arg->value.obj.properties);
zend_hash_init(arg->value.obj.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(arg->value.obj.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
arg->type = IS_OBJECT;
arg->value.obj.ce = class_type;
return SUCCESS;
}
ZEND_API inline int _object_init(zval *arg ZEND_FILE_LINE_DC)
{
return _object_init_ex(arg, &zend_standard_class_def ZEND_FILE_LINE_CC);
}
ZEND_API inline int add_assoc_function(zval *arg, char *key,void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS))
{
zend_error(E_WARNING, "add_assoc_function() is no longer supported");
return FAILURE;
}
ZEND_API inline int add_assoc_long(zval *arg, char *key, long n)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_LONG;
tmp->value.lval = n;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_unset(zval *arg, char *key)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_NULL;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_bool(zval *arg, char *key, int b)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_BOOL;
tmp->value.lval = b;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_resource(zval *arg, char *key, int r)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_RESOURCE;
tmp->value.lval = r;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_double(zval *arg, char *key, double d)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_DOUBLE;
tmp->value.dval = d;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_string(zval *arg, char *key, char *str, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_assoc_stringl(zval *arg, char *key, char *str, uint length, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_index_long(zval *arg, uint index, long n)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_LONG;
tmp->value.lval = n;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_index_unset(zval *arg, uint index)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_NULL;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_index_bool(zval *arg, uint index, int b)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_BOOL;
tmp->value.lval = b;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_index_resource(zval *arg, uint index, int r)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_RESOURCE;
tmp->value.lval = r;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_index_double(zval *arg, uint index, double d)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_DOUBLE;
tmp->value.dval = d;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_index_string(zval *arg, uint index, char *str, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_index_stringl(zval *arg, uint index, char *str, uint length, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_next_index_long(zval *arg, long n)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_LONG;
tmp->value.lval = n;
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_next_index_unset(zval *arg)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_NULL;
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_next_index_bool(zval *arg, int b)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_BOOL;
tmp->value.lval = b;
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_next_index_resource(zval *arg, int r)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_RESOURCE;
tmp->value.lval = r;
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_next_index_double(zval *arg, double d)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_DOUBLE;
tmp->value.dval = d;
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_next_index_string(zval *arg, char *str, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *),NULL);
}
ZEND_API inline int add_get_assoc_string(zval *arg, char *key, char *str, void **dest, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), dest);
}
ZEND_API inline int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length, void **dest, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), dest);
}
ZEND_API inline int add_get_index_long(zval *arg, uint index, long l, void **dest)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_LONG;
tmp->value.lval = l;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
}
ZEND_API inline int add_get_index_double(zval *arg, uint index, double d, void **dest)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_DOUBLE;
tmp->value.dval= d;
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
}
ZEND_API inline int add_get_index_string(zval *arg, uint index, char *str, void **dest, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
}
ZEND_API inline int add_get_index_stringl(zval *arg, uint index, char *str, uint length, void **dest, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
}
ZEND_API inline int add_property_long(zval *arg, char *key, long n)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_LONG;
tmp->value.lval = n;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_bool(zval *arg, char *key, int b)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_BOOL;
tmp->value.lval = b;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_unset(zval *arg, char *key)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_NULL;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_resource(zval *arg, char *key, long n)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_RESOURCE;
tmp->value.lval = n;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_double(zval *arg, char *key, double d)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_DOUBLE;
tmp->value.dval = d;
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_string(zval *arg, char *key, char *str, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = strlen(str);
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API inline int add_property_stringl(zval *arg, char *key, char *str, uint length, int duplicate)
{
zval *tmp;
ALLOC_ZVAL(tmp);
tmp->type = IS_STRING;
tmp->value.str.len = length;
if (duplicate) {
tmp->value.str.val = estrndup(str,tmp->value.str.len);
} else {
tmp->value.str.val = str;
}
INIT_PZVAL(tmp);
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
}
ZEND_API int zend_startup_module(zend_module_entry *module)
{
if (module) {
module->module_number = zend_next_free_module();
if (module->module_startup_func) {
ELS_FETCH();
if (module->module_startup_func(MODULE_PERSISTENT, module->module_number ELS_CC)==FAILURE) {
zend_error(E_CORE_ERROR,"Unable to start %s module",module->name);
return FAILURE;
}
}
module->type = MODULE_PERSISTENT;
zend_register_module(module);
}
return SUCCESS;
}
/* registers all functions in *library_functions in the function hash */
int zend_register_functions(zend_function_entry *functions, HashTable *function_table, int type)
{
zend_function_entry *ptr = functions;
zend_function function;
zend_internal_function *internal_function = (zend_internal_function *)&function;
int count=0,unload=0;
HashTable *target_function_table = function_table;
int error_type;
CLS_FETCH();
if (type==MODULE_PERSISTENT) {
error_type = E_CORE_WARNING;
} else {
error_type = E_WARNING;
}
if (!target_function_table) {
target_function_table = CG(function_table);
}
internal_function->type = ZEND_INTERNAL_FUNCTION;
while (ptr->fname) {
internal_function->handler = ptr->handler;
internal_function->arg_types = ptr->func_arg_types;
internal_function->function_name = ptr->fname;
if (!internal_function->handler) {
zend_error(error_type, "Null function defined as active function");
zend_unregister_functions(functions, count, target_function_table);
return FAILURE;
}
if (zend_hash_add(target_function_table, ptr->fname, strlen(ptr->fname)+1, &function, sizeof(zend_function), NULL) == FAILURE) {
unload=1;
break;
}
ptr++;
count++;
}
if (unload) { /* before unloading, display all remaining bad function in the module */
while (ptr->fname) {
if (zend_hash_exists(target_function_table, ptr->fname, strlen(ptr->fname)+1)) {
zend_error(error_type, "Function registration failed - duplicate name - %s",ptr->fname);
}
ptr++;
}
zend_unregister_functions(functions, count, target_function_table);
return FAILURE;
}
return SUCCESS;
}
/* count=-1 means erase all functions, otherwise,
* erase the first count functions
*/
void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table)
{
zend_function_entry *ptr = functions;
int i=0;
HashTable *target_function_table = function_table;
CLS_FETCH();
if (!target_function_table) {
target_function_table = CG(function_table);
}
while (ptr->fname) {
if (count!=-1 && i>=count) {
break;
}
#if 0
zend_printf("Unregistering %s()\n", ptr->fname);
#endif
zend_hash_del(target_function_table, ptr->fname, strlen(ptr->fname)+1);
ptr++;
i++;
}
}
ZEND_API int zend_register_module(zend_module_entry *module)
{
#if 0
zend_printf("%s: Registering module %d\n",module->name, module->module_number);
#endif
if (module->functions && zend_register_functions(module->functions, NULL, module->type)==FAILURE) {
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load",module->name);
return FAILURE;
}
module->module_started=1;
return zend_hash_add(&module_registry, module->name,strlen(module->name)+1,(void *)module,sizeof(zend_module_entry),NULL);
}
void module_destructor(zend_module_entry *module)
{
if (module->type == MODULE_TEMPORARY) {
zend_clean_module_rsrc_dtors(module->module_number);
clean_module_constants(module->module_number);
if (module->request_shutdown_func)
module->request_shutdown_func(module->type, module->module_number);
}
if (module->module_started && module->module_shutdown_func) {
#if 0
zend_printf("%s: Module shutdown\n",module->name);
#endif
module->module_shutdown_func(module->type, module->module_number);
}
module->module_started=0;
if (module->functions) {
zend_unregister_functions(module->functions, -1, NULL);
}
#if HAVE_LIBDL
if (module->handle) {
dlclose(module->handle);
}
#endif
}
/* call request startup for all modules */
int module_registry_request_startup(zend_module_entry *module)
{
if (module->request_startup_func) {
ELS_FETCH();
#if 0
zend_printf("%s: Request startup\n",module->name);
#endif
if (module->request_startup_func(module->type, module->module_number ELS_CC)==FAILURE) {
zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
exit(1);
}
}
return 0;
}
/* for persistent modules - call request shutdown and flag NOT to erase
* for temporary modules - do nothing, and flag to erase
*/
int module_registry_cleanup(zend_module_entry *module)
{
switch(module->type) {
case MODULE_PERSISTENT:
if (module->request_shutdown_func) {
#if 0
zend_printf("%s: Request shutdown\n",module->name);
#endif
module->request_shutdown_func(module->type, module->module_number);
}
return 0;
break;
case MODULE_TEMPORARY:
return 1;
break;
}
return 0;
}
/* return the next free module number */
int zend_next_free_module(void)
{
return ++module_count;
}
/* If parent_ce is not NULL then it inherits from parent_ce
* If parent_ce is NULL and parent_name isn't then it looks for the parent and inherits from it
* If both parent_ce and parent_name are NULL it does a regular class registration
* If parent_name is specified but not found NULL is returned
*/
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name)
{
zend_class_entry *register_class;
CLS_FETCH();
if (!parent_ce && parent_name) {
if (zend_hash_find(CG(class_table), parent_name, strlen(parent_name)+1, (void **) &parent_ce)==FAILURE) {
return NULL;
}
}
register_class = zend_register_internal_class(class_entry);
if (parent_ce) {
do_inheritance(register_class, parent_ce);
}
return register_class;
}
ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry)
{
zend_class_entry *register_class;
char *lowercase_name = zend_strndup(class_entry->name, class_entry->name_length);
CLS_FETCH();
zend_str_tolower(lowercase_name, class_entry->name_length);
class_entry->type = ZEND_INTERNAL_CLASS;
class_entry->parent = NULL;
class_entry->refcount = (int *) malloc(sizeof(int));
*class_entry->refcount = 1;
class_entry->constants_updated = 0;
zend_hash_init(&class_entry->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1);
zend_hash_init(&class_entry->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1);
if (class_entry->builtin_functions) {
zend_register_functions(class_entry->builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
}
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, class_entry, sizeof(zend_class_entry), (void **) &register_class);
free(lowercase_name);
return register_class;
}
ZEND_API zend_module_entry *zend_get_module(int module_number)
{
zend_module_entry *module;
if (zend_hash_index_find(&module_registry, module_number, (void **) &module)==SUCCESS) {
return module;
} else {
return NULL;
}
}
ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
int is_ref, int num_symbol_tables, ...)
{
HashTable *symbol_table;
va_list symbol_table_list;
if (num_symbol_tables <= 0) return FAILURE;
symbol->is_ref = is_ref;
va_start(symbol_table_list, num_symbol_tables);
while(num_symbol_tables-- > 0) {
symbol_table = va_arg(symbol_table_list, HashTable *);
zend_hash_update(symbol_table, name, name_length + 1, &symbol, sizeof(zval *), NULL);
zval_add_ref(&symbol);
}
va_end(symbol_table_list);
return SUCCESS;
}
/* Disabled functions support */
static ZEND_FUNCTION(display_disabled_function)
{
zend_error(E_WARNING, "%s() has been disabled for security reasons.", get_active_function_name());
}
static zend_function_entry disabled_function[] = {
ZEND_FE(display_disabled_function, NULL)
{ NULL, NULL, NULL }
};
ZEND_API int zend_disable_function(char *function_name, uint function_name_length)
{
CLS_FETCH();
if (zend_hash_del(CG(function_table), function_name, function_name_length+1)==FAILURE) {
return FAILURE;
}
disabled_function[0].fname = function_name;
return zend_register_functions(disabled_function, CG(function_table), MODULE_PERSISTENT);
}
+426
View File
@@ -0,0 +1,426 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_API_H
#define ZEND_API_H
#include "modules.h"
#include "zend_list.h"
#include "zend_fast_cache.h"
#include "zend_operators.h"
#include "zend_variables.h"
#include "zend_execute.h"
#define ZEND_FN(name) zend_if_##name
#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_NAMED_FE(zend_name, name, arg_types) { #zend_name, name, arg_types },
#define ZEND_FE(name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(name), arg_types)
#define ZEND_FALIAS(name, alias, arg_types) ZEND_NAMED_FE(name, ZEND_FN(alias), arg_types)
#define ZEND_MINIT(module) zend_minit_##module
#define ZEND_MSHUTDOWN(module) zend_mshutdown_##module
#define ZEND_RINIT(module) zend_rinit_##module
#define ZEND_RSHUTDOWN(module) zend_rshutdown_##module
#define ZEND_MINFO(module) zend_info_##module
#define ZEND_GINIT(module) zend_ginit_##module
#define ZEND_GSHUTDOWN(module) zend_gshutdown_##module
#define ZEND_MINIT_FUNCTION(module) int ZEND_MINIT(module)(INIT_FUNC_ARGS)
#define ZEND_MSHUTDOWN_FUNCTION(module) int ZEND_MSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS)
#define ZEND_RINIT_FUNCTION(module) int ZEND_RINIT(module)(INIT_FUNC_ARGS)
#define ZEND_RSHUTDOWN_FUNCTION(module) int ZEND_RSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS)
#define ZEND_MINFO_FUNCTION(module) void ZEND_MINFO(module)(ZEND_MODULE_INFO_FUNC_ARGS)
#define ZEND_GINIT_FUNCTION(module) int ZEND_GINIT(module)(GINIT_FUNC_ARGS)
#define ZEND_GSHUTDOWN_FUNCTION(module) int ZEND_GSHUTDOWN(module)(void)
#define ZEND_GET_MODULE(name) \
ZEND_DLEXPORT zend_module_entry *get_module(void) { return &name##_module_entry; }
#define ZEND_BEGIN_MODULE_GLOBALS(module_name) \
typedef struct _zend_##module_name##_globals {
#define ZEND_END_MODULE_GLOBALS(module_name) \
} zend_##module_name##_globals;
#ifdef ZTS
#define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
static ts_rsrc_id module_name##_globals_id;
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
module_name##_globals_id = ts_allocate_id(sizeof(zend_##module_name##_globals), (ts_allocate_ctor) globals_ctor, (ts_allocate_dtor) globals_dtor);
#else
#define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
static zend_##module_name##_globals module_name##_globals;
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
globals_ctor(&module_name##_globals);
#endif
#define INIT_CLASS_ENTRY(class_container, class_name, functions) \
{ \
class_container.name = strdup(class_name); \
class_container.name_length = sizeof(class_name)-1; \
class_container.builtin_functions = functions; \
class_container.handle_function_call = NULL; \
class_container.handle_property_get = NULL; \
class_container.handle_property_set = NULL; \
}
#define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \
{ \
class_container.name = strdup(class_name); \
class_container.name_length = sizeof(class_name)-1; \
class_container.builtin_functions = functions; \
class_container.handle_function_call = handle_fcall; \
class_container.handle_property_get = handle_propget; \
class_container.handle_property_set = handle_propset; \
}
int zend_next_free_module(void);
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
ZEND_API int zend_get_parameters_array(int ht, int param_count, zval **argument_array);
ZEND_API int zend_get_parameters_ex(int param_count, ...);
ZEND_API int zend_get_parameters_array_ex(int param_count, zval ***argument_array);
ZEND_API int ParameterPassedByReference(int ht, uint n);
int zend_register_functions(zend_function_entry *functions, HashTable *function_table, int type);
void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table);
ZEND_API int zend_register_module(zend_module_entry *module_entry);
ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry);
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name);
ZEND_API zend_module_entry *zend_get_module(int module_number);
ZEND_API int zend_disable_function(char *function_name, uint function_name_length);
ZEND_API void wrong_param_count(void);
#define getThis() (this_ptr)
#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT()
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)
#define ARG_COUNT(dummy) (ht)
#define ZEND_NUM_ARGS() (ht)
#define ZEND_WRONG_PARAM_COUNT() { wrong_param_count(); return; }
#define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret) { wrong_param_count(); return ret; }
#ifndef ZEND_WIN32
#define DLEXPORT
#endif
ZEND_API int zend_startup_module(zend_module_entry *module);
#define array_init(arg) _array_init((arg) ZEND_FILE_LINE_CC)
#define object_init(arg) _object_init((arg) ZEND_FILE_LINE_CC)
#define object_init_ex(arg, ce) _object_init_ex((arg), (ce) ZEND_FILE_LINE_CC)
ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC);
ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC);
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC);
/* no longer supported */
ZEND_API int add_assoc_function(zval *arg, char *key,void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));
ZEND_API int add_assoc_long(zval *arg, char *key, long n);
ZEND_API int add_assoc_unset(zval *arg, char *key);
ZEND_API int add_assoc_bool(zval *arg, char *key, int b);
ZEND_API int add_assoc_resource(zval *arg, char *key, int r);
ZEND_API int add_assoc_double(zval *arg, char *key, double d);
ZEND_API int add_assoc_string(zval *arg, char *key, char *str, int duplicate);
ZEND_API int add_assoc_stringl(zval *arg, char *key, char *str, uint length, int duplicate);
ZEND_API int add_index_long(zval *arg, uint idx, long n);
ZEND_API int add_index_unset(zval *arg, uint idx);
ZEND_API int add_index_bool(zval *arg, uint idx, int b);
ZEND_API int add_index_resource(zval *arg, uint idx, int r);
ZEND_API int add_index_double(zval *arg, uint idx, double d);
ZEND_API int add_index_string(zval *arg, uint idx, char *str, int duplicate);
ZEND_API int add_index_stringl(zval *arg, uint idx, char *str, uint length, int duplicate);
ZEND_API int add_next_index_long(zval *arg, long n);
ZEND_API int add_next_index_unset(zval *arg);
ZEND_API int add_next_index_bool(zval *arg, int b);
ZEND_API int add_next_index_resource(zval *arg, int r);
ZEND_API int add_next_index_double(zval *arg, double d);
ZEND_API int add_next_index_string(zval *arg, char *str, int duplicate);
ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate);
ZEND_API int add_get_index_long(zval *arg, uint idx, long l, void **dest);
ZEND_API int add_get_index_double(zval *arg, uint idx, double d, void **dest);
ZEND_API int add_get_assoc_string(zval *arg, char *key, char *str, void **dest, int duplicate);
ZEND_API int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length, void **dest, int duplicate);
ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, int duplicate);
ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[]);
ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table);
ZEND_API int add_property_long(zval *arg, char *key, long l);
ZEND_API int add_property_unset(zval *arg, char *key);
ZEND_API int add_property_bool(zval *arg, char *key, int b);
ZEND_API int add_property_resource(zval *arg, char *key, long r);
ZEND_API int add_property_double(zval *arg, char *key, double d);
ZEND_API int add_property_string(zval *arg, char *key, char *str, int duplicate);
ZEND_API int add_property_stringl(zval *arg, char *key, char *str, uint length, int duplicate);
ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
int is_ref, int num_symbol_tables, ...);
#define add_method(arg,key,method) add_assoc_function((arg),(key),(method))
#define ZVAL_RESOURCE(z,l) { \
(z)->type = IS_RESOURCE; \
(z)->value.lval = l; \
}
#define ZVAL_BOOL(z,b) { \
(z)->type = IS_BOOL; \
(z)->value.lval = b; \
}
#define ZVAL_NULL(z) { \
(z)->type = IS_NULL; \
}
#define ZVAL_LONG(z,l) { \
(z)->type = IS_LONG; \
(z)->value.lval = l; \
}
#define ZVAL_DOUBLE(z,d) { \
(z)->type = IS_DOUBLE; \
(z)->value.dval = d; \
}
#define ZVAL_STRING(z,s,duplicate) { \
char *__s=(s); \
(z)->value.str.len = strlen(__s); \
(z)->value.str.val = (duplicate?estrndup(__s,(z)->value.str.len):__s); \
(z)->type = IS_STRING; \
}
#define ZVAL_STRINGL(z,s,l,duplicate) { \
char *__s=(s); int __l=l; \
(z)->value.str.len = __l; \
(z)->value.str.val = (duplicate?estrndup(__s,__l):__s); \
(z)->type = IS_STRING; \
}
#define ZVAL_EMPTY_STRING(z) { \
(z)->value.str.len = 0; \
(z)->value.str.val = empty_string; \
(z)->type = IS_STRING; \
}
#define ZVAL_FALSE { (z)->value.lval = 0; (z)->type = IS_BOOL; }
#define ZVAL_TRUE { (z)->value.lval = 1; (z)->type = IS_BOOL; }
#define RETVAL_RESOURCE(l) { \
return_value->type = IS_RESOURCE;\
return_value->value.lval = l; \
}
#define RETVAL_BOOL(b) { \
return_value->type = IS_BOOL; \
return_value->value.lval = b; \
}
#define RETVAL_NULL() { \
return_value->type = IS_NULL; \
}
#define RETVAL_LONG(l) { \
return_value->type = IS_LONG; \
return_value->value.lval = l; \
}
#define RETVAL_DOUBLE(d) { \
return_value->type = IS_DOUBLE; \
return_value->value.dval = d; \
}
#define RETVAL_STRING(s,duplicate) { \
char *__s=(s); \
return_value->value.str.len = strlen(__s); \
return_value->value.str.val = (duplicate?estrndup(__s,return_value->value.str.len):__s); \
return_value->type = IS_STRING; \
}
#define RETVAL_STRINGL(s,l,duplicate) { \
char *__s=(s); int __l=l; \
return_value->value.str.len = __l; \
return_value->value.str.val = (duplicate?estrndup(__s,__l):__s); \
return_value->type = IS_STRING; \
}
#define RETVAL_EMPTY_STRING() { \
return_value->value.str.len = 0; \
return_value->value.str.val = empty_string; \
return_value->type = IS_STRING; \
}
#define RETVAL_FALSE { return_value->value.lval = 0; return_value->type = IS_BOOL; }
#define RETVAL_TRUE { return_value->value.lval = 1; return_value->type = IS_BOOL; }
#define RETURN_RESOURCE(l) { \
return_value->type = IS_RESOURCE;\
return_value->value.lval = l; \
return; \
}
#define RETURN_BOOL(b) { \
return_value->type = IS_BOOL; \
return_value->value.lval = b; \
return; \
}
#define RETURN_NULL() { \
return_value->type = IS_NULL; \
return; \
}
#define RETURN_LONG(l) { \
return_value->type = IS_LONG; \
return_value->value.lval = l; \
return; \
}
#define RETURN_DOUBLE(d) { \
return_value->type = IS_DOUBLE; \
return_value->value.dval = d; \
return; \
}
#define RETURN_STRING(s,duplicate) { \
char *__s=(s); \
return_value->value.str.len = strlen(__s); \
return_value->value.str.val = (duplicate?estrndup(__s,return_value->value.str.len):__s); \
return_value->type = IS_STRING; \
return; \
}
#define RETURN_STRINGL(s,l,duplicate) { \
char *__s=(s); int __l=l; \
return_value->value.str.len = __l; \
return_value->value.str.val = (duplicate?estrndup(__s,__l):__s); \
return_value->type = IS_STRING; \
return; \
}
#define RETURN_EMPTY_STRING() { \
return_value->value.str.len = 0; \
return_value->value.str.val = empty_string; \
return_value->type = IS_STRING; \
return; \
}
#define RETURN_FALSE { RETVAL_FALSE; return; }
#define RETURN_TRUE { RETVAL_TRUE; return; }
#define SET_VAR_STRING(n,v) { \
{ \
zval *var; \
char *str=(v); /* prevent 'v' from being evaluated more than once */ \
\
ALLOC_ZVAL(var); \
var->value.str.val = (str); \
var->value.str.len = strlen((str)); \
var->type = IS_STRING; \
ZEND_SET_GLOBAL_VAR(n, var); \
} \
}
#define SET_VAR_STRINGL(n,v,l) { \
{ \
zval *var; \
\
ALLOC_ZVAL(var); \
var->value.str.val = (v); \
var->value.str.len = (l); \
var->type = IS_STRING; \
ZEND_SET_GLOBAL_VAR(n, var); \
} \
}
#define SET_VAR_LONG(n,v) { \
{ \
zval *var; \
\
ALLOC_ZVAL(var); \
var->value.lval = (v); \
var->type = IS_LONG; \
ZEND_SET_GLOBAL_VAR(n, var); \
} \
}
#define SET_VAR_DOUBLE(n,v) { \
{ \
zval *var; \
\
ALLOC_ZVAL(var); \
var->value.dval = (v); \
var->type = IS_DOUBLE; \
ZEND_SET_GLOBAL_VAR(n, var); \
} \
}
#define ZEND_SET_SYMBOL(symtable, name, var) \
{ \
char *_name = (name); \
\
ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0); \
}
#define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref) \
{ \
zval **orig_var; \
\
if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS \
&& PZVAL_IS_REF(*orig_var)) { \
(var)->refcount = (*orig_var)->refcount; \
(var)->is_ref = 1; \
\
if (_refcount) { \
(var)->refcount += _refcount-1; \
} \
zval_dtor(*orig_var); \
**orig_var = *(var); \
FREE_ZVAL(var); \
} else { \
(var)->is_ref = _is_ref; \
if (_refcount) { \
(var)->refcount = _refcount; \
} \
zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL); \
} \
}
#define ZEND_SET_GLOBAL_VAR(name, var) \
ZEND_SET_SYMBOL(&EG(symbol_table), name, var)
#define ZEND_SET_GLOBAL_VAR_WITH_LENGTH(name, name_length, var, _refcount, _is_ref) \
ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), name, name_length, var, _refcount, _is_ref)
#define HASH_OF(p) ((p)->type==IS_ARRAY ? (p)->value.ht : (((p)->type==IS_OBJECT ? (p)->value.obj.properties : NULL)))
#define ZVAL_IS_NULL(z) ((z)->type==IS_NULL)
#endif /* ZEND_API_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+693
View File
@@ -0,0 +1,693 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include <stdlib.h>
#include "zend.h"
#include "zend_alloc.h"
#include "zend_globals.h"
#include "zend_fast_cache.h"
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifndef ZTS
ZEND_API zend_alloc_globals alloc_globals;
#endif
#define ZEND_DISABLE_MEMORY_CACHE 0
#if ZEND_DEBUG
# define END_MAGIC_SIZE sizeof(long)
# define END_ALIGNMENT(size) (((size)%PLATFORM_ALIGNMENT)?(PLATFORM_ALIGNMENT-((size)%PLATFORM_ALIGNMENT)):0)
#else
# define END_MAGIC_SIZE 0
# define END_ALIGNMENT(size) 0
#endif
# if MEMORY_LIMIT
# if ZEND_DEBUG
#define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, __zend_filename, __zend_lineno)
# else
#define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL,0)
# endif
#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\
if (AG(memory_limit)<AG(allocated_memory)) {\
if ((AG(memory_limit)+1048576)<AG(allocated_memory)) { \
/* failed to handle this gracefully, exit() */ \
exit(1); \
} \
if (!AG(memory_exhausted)) { \
if (!file) { \
zend_error(E_ERROR,"Allowed memory size of %d bytes exhausted (tried to allocate %d bytes)", AG(memory_limit),s); \
} else { \
zend_error(E_ERROR,"Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes)", AG(memory_limit), file, lineno, s); \
} \
AG(memory_exhausted)=1; \
} \
} \
}
# endif
#ifndef CHECK_MEMORY_LIMIT
#define CHECK_MEMORY_LIMIT(s, rs)
#endif
#define REMOVE_POINTER_FROM_LIST(p) \
if (!p->persistent && p==AG(head)) { \
AG(head) = p->pNext; \
} else if (p->persistent && p==AG(phead)) { \
AG(phead) = p->pNext; \
} else { \
p->pLast->pNext = p->pNext; \
} \
if (p->pNext) { \
p->pNext->pLast = p->pLast; \
}
#define ADD_POINTER_TO_LIST(p) \
if (p->persistent) { \
p->pNext = AG(phead); \
if (AG(phead)) { \
AG(phead)->pLast = p; \
} \
AG(phead) = p; \
} else { \
p->pNext = AG(head); \
if (AG(head)) { \
AG(head)->pLast = p; \
} \
AG(head) = p; \
} \
p->pLast = (zend_mem_header *) NULL;
#define DECLARE_CACHE_VARS \
unsigned int real_size; \
unsigned int cache_index;
#define REAL_SIZE(size) ((size+7) & ~0x7)
#define CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size) \
real_size = REAL_SIZE(size); \
cache_index = real_size >> 3;
#define SIZE real_size
#define CACHE_INDEX cache_index
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p;
DECLARE_CACHE_VARS
ALS_FETCH();
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]];
#if ZEND_DEBUG
p->filename = __zend_filename;
p->lineno = __zend_lineno;
p->orig_filename = __zend_orig_filename;
p->orig_lineno = __zend_orig_lineno;
p->magic = MEM_BLOCK_START_MAGIC;
p->reported = 0;
AG(cache_stats)[CACHE_INDEX][1]++;
#endif
p->persistent = 0;
p->cached = 0;
p->size = size;
HANDLE_BLOCK_INTERRUPTIONS();
ADD_POINTER_TO_LIST(p);
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *)((char *)p + sizeof(zend_mem_header) + PLATFORM_PADDING);
} else {
#if ZEND_DEBUG
if (CACHE_INDEX<MAX_CACHED_MEMORY) {
AG(cache_stats)[CACHE_INDEX][0]++;
}
#endif
p = (zend_mem_header *) malloc(sizeof(zend_mem_header) + SIZE + PLATFORM_PADDING + END_ALIGNMENT(SIZE) + END_MAGIC_SIZE);
}
HANDLE_BLOCK_INTERRUPTIONS();
if (!p) {
fprintf(stderr,"FATAL: emalloc(): Unable to allocate %ld bytes\n", (long) size);
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
kill(getpid(), SIGSEGV);
#else
exit(1);
#endif
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *)p;
}
p->persistent = p->cached = 0;
ADD_POINTER_TO_LIST(p);
p->size = size; /* Save real size for correct cache output */
#if ZEND_DEBUG
p->filename = __zend_filename;
p->lineno = __zend_lineno;
p->orig_filename = __zend_orig_filename;
p->orig_lineno = __zend_orig_lineno;
p->magic = MEM_BLOCK_START_MAGIC;
p->reported = 0;
*((long *)(((char *) p) + sizeof(zend_mem_header)+SIZE+PLATFORM_PADDING+END_ALIGNMENT(SIZE))) = MEM_BLOCK_END_MAGIC;
#endif
#if MEMORY_LIMIT
CHECK_MEMORY_LIMIT(size, SIZE);
#endif
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *)((char *)p + sizeof(zend_mem_header) + PLATFORM_PADDING);
}
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - PLATFORM_PADDING);
DECLARE_CACHE_VARS
ALS_FETCH();
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(p->size);
#if ZEND_DEBUG
if (!_mem_block_check(ptr, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)) {
return;
}
memset(ptr, 0x5a, SIZE);
#endif
if (!ZEND_DISABLE_MEMORY_CACHE
&& !p->persistent && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] < MAX_CACHED_ENTRIES)) {
AG(cache)[CACHE_INDEX][AG(cache_count)[CACHE_INDEX]++] = p;
p->cached = 1;
#if ZEND_DEBUG
p->magic = MEM_BLOCK_CACHED_MAGIC;
#endif
HANDLE_BLOCK_INTERRUPTIONS();
REMOVE_POINTER_FROM_LIST(p);
HANDLE_UNBLOCK_INTERRUPTIONS();
return;
}
HANDLE_BLOCK_INTERRUPTIONS();
REMOVE_POINTER_FROM_LIST(p);
#if MEMORY_LIMIT
AG(allocated_memory) -= SIZE;
#endif
free(p);
HANDLE_UNBLOCK_INTERRUPTIONS();
}
ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
void *p;
int final_size=size*nmemb;
HANDLE_BLOCK_INTERRUPTIONS();
p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (!p) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *) p;
}
memset(p,(int)NULL, final_size);
HANDLE_UNBLOCK_INTERRUPTIONS();
return p;
}
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-PLATFORM_PADDING);
zend_mem_header *orig = p;
DECLARE_CACHE_VARS
ALS_FETCH();
if (!ptr) {
return _emalloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
HANDLE_BLOCK_INTERRUPTIONS();
REMOVE_POINTER_FROM_LIST(p);
p = (zend_mem_header *) realloc(p,sizeof(zend_mem_header)+SIZE+PLATFORM_PADDING+END_ALIGNMENT(SIZE)+END_MAGIC_SIZE);
if (!p) {
if (!allow_failure) {
fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
kill(getpid(), SIGSEGV);
#else
exit(1);
#endif
}
ADD_POINTER_TO_LIST(orig);
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *)NULL;
}
ADD_POINTER_TO_LIST(p);
#if ZEND_DEBUG
p->filename = __zend_filename;
p->lineno = __zend_lineno;
p->magic = MEM_BLOCK_START_MAGIC;
*((long *)(((char *) p) + sizeof(zend_mem_header)+SIZE+PLATFORM_PADDING+END_ALIGNMENT(SIZE))) = MEM_BLOCK_END_MAGIC;
#endif
#if MEMORY_LIMIT
CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size));
#endif
p->size = size;
HANDLE_UNBLOCK_INTERRUPTIONS();
return (void *)((char *)p+sizeof(zend_mem_header)+PLATFORM_PADDING);
}
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
int length;
char *p;
length = strlen(s)+1;
HANDLE_BLOCK_INTERRUPTIONS();
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (!p) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return (char *)NULL;
}
HANDLE_UNBLOCK_INTERRUPTIONS();
memcpy(p,s,length);
return p;
}
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
char *p;
HANDLE_BLOCK_INTERRUPTIONS();
p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (!p) {
HANDLE_UNBLOCK_INTERRUPTIONS();
return (char *)NULL;
}
HANDLE_UNBLOCK_INTERRUPTIONS();
memcpy(p,s,length);
p[length]=0;
return p;
}
ZEND_API char *zend_strndup(const char *s, uint length)
{
char *p;
p = (char *) malloc(length+1);
if (!p) {
return (char *)NULL;
}
if (length) {
memcpy(p,s,length);
}
p[length]=0;
return p;
}
ZEND_API int zend_set_memory_limit(unsigned int memory_limit)
{
#if MEMORY_LIMIT
ALS_FETCH();
AG(memory_limit) = memory_limit;
return SUCCESS;
#else
return FAILURE;
#endif
}
ZEND_API void start_memory_manager(ALS_D)
{
#ifndef ZTS
int i, j;
void *cached_entries[MAX_CACHED_MEMORY][MAX_CACHED_ENTRIES];
#endif
AG(phead) = AG(head) = NULL;
#if MEMORY_LIMIT
AG(memory_limit)=1<<30; /* rediculous limit, effectively no limit */
AG(allocated_memory)=0;
AG(memory_exhausted)=0;
#endif
memset(AG(fast_cache_list_head), 0, sizeof(AG(fast_cache_list_head)));
memset(AG(cache_count),0,sizeof(AG(cache_count)));
#ifndef ZTS
/* Initialize cache, to prevent fragmentation */
/* We can't do this in ZTS mode, because calling emalloc() from within start_memory_manager()
* will yield an endless recursion calling to alloc_globals_ctor()
*/
for (i=1; i<MAX_CACHED_MEMORY; i++) {
for (j=0; j<PRE_INIT_CACHE_ENTRIES; j++) {
cached_entries[i][j] = emalloc(8*i);
}
}
for (i=1; i<MAX_CACHED_MEMORY; i++) {
for (j=0; j<PRE_INIT_CACHE_ENTRIES; j++) {
efree(cached_entries[i][j]);
}
}
#endif
#if ZEND_DEBUG
memset(AG(cache_stats), 0, sizeof(AG(cache_stats)));
memset(AG(fast_cache_stats), 0, sizeof(AG(fast_cache_stats)));
#endif
}
ZEND_API void shutdown_memory_manager(int silent, int clean_cache)
{
zend_mem_header *p, *t;
unsigned int fci, i, j;
#if ZEND_DEBUG
int had_leaks=0;
#endif
zend_fast_cache_list_entry *fast_cache_list_entry, *next_fast_cache_list_entry;
ALS_FETCH();
for (fci=0; fci<MAX_FAST_CACHE_TYPES; fci++) {
fast_cache_list_entry = AG(fast_cache_list_head)[fci];
while (fast_cache_list_entry) {
next_fast_cache_list_entry = fast_cache_list_entry->next;
efree(fast_cache_list_entry);
fast_cache_list_entry = next_fast_cache_list_entry;
}
AG(fast_cache_list_head)[fci] = NULL;
}
p=AG(head);
t=AG(head);
while (t) {
if (!t->cached || clean_cache) {
#if ZEND_DEBUG
if (!t->cached && !t->reported) {
zend_mem_header *iterator;
int total_leak=0, total_leak_count=0;
had_leaks=1;
if (!silent) {
zend_message_dispatcher(ZMSG_MEMORY_LEAK_DETECTED, t);
}
t->reported = 1;
for (iterator=t->pNext; iterator; iterator=iterator->pNext) {
if (!iterator->cached
&& iterator->filename==t->filename
&& iterator->lineno==t->lineno) {
total_leak += iterator->size;
total_leak_count++;
iterator->reported = 1;
}
}
if (!silent && total_leak_count>0) {
zend_message_dispatcher(ZMSG_MEMORY_LEAK_REPEATED, (void *) (long) (total_leak_count));
}
}
#endif
#if MEMORY_LIMIT
AG(allocated_memory) -= t->size;
#endif
p = t->pNext;
REMOVE_POINTER_FROM_LIST(t);
free(t);
t = p;
} else {
t = t->pNext;
}
}
if(clean_cache) {
for (i=1; i<MAX_CACHED_MEMORY; i++) {
for (j=0; j<AG(cache_count)[i]; j++) {
free(AG(cache)[i][j]);
}
}
}
#if MEMORY_LIMIT
AG(memory_exhausted)=0;
#endif
#if (ZEND_DEBUG)
do {
zval display_memory_cache_stats;
int i, j;
if (clean_cache) {
/* we're shutting down completely, don't even touch the INI subsystem */
break;
}
if (zend_get_ini_entry("display_memory_cache_stats", sizeof("display_memory_cache_stats"), &display_memory_cache_stats)==FAILURE) {
break;
}
if (!atoi(display_memory_cache_stats.value.str.val)) {
break;
}
fprintf(stderr, "Memory cache statistics\n"
"-----------------------\n\n"
"[zval, %2ld]\t\t%d / %d (%.2f%%)\n"
"[hash, %2ld]\t\t%d / %d (%.2f%%)\n",
(long) sizeof(zval),
AG(fast_cache_stats)[ZVAL_CACHE_LIST][1], AG(fast_cache_stats)[ZVAL_CACHE_LIST][0]+AG(fast_cache_stats)[ZVAL_CACHE_LIST][1],
((double) AG(fast_cache_stats)[ZVAL_CACHE_LIST][1] / (AG(fast_cache_stats)[ZVAL_CACHE_LIST][0]+AG(fast_cache_stats)[ZVAL_CACHE_LIST][1]))*100,
(long) sizeof(HashTable),
AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][1], AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][0]+AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][1],
((double) AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][1] / (AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][0]+AG(fast_cache_stats)[HASHTABLE_CACHE_LIST][1]))*100);
for (i=0; i<MAX_CACHED_MEMORY; i+=2) {
fprintf(stderr, "[%2d, %2d]\t\t", i, i+1);
for (j=0; j<2; j++) {
fprintf(stderr, "%d / %d (%.2f%%)\t\t",
AG(cache_stats)[i+j][1], AG(cache_stats)[i+j][0]+AG(cache_stats)[i+j][1],
((double) AG(cache_stats)[i+j][1] / (AG(cache_stats)[i+j][0]+AG(cache_stats)[i+j][1]))*100);
}
fprintf(stderr, "\n");
}
} while (0);
#endif
}
#if ZEND_DEBUG
void zend_debug_alloc_output(char *format, ...)
{
char output_buf[256];
va_list args;
va_start(args, format);
vsprintf(output_buf, format, args);
va_end(args);
#ifdef ZEND_WIN32
OutputDebugString(output_buf);
#else
fprintf(stderr, "%s", output_buf);
#endif
}
ZEND_API int _mem_block_check(void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - PLATFORM_PADDING);
int no_cache_notice=0;
int valid_beginning=1;
int had_problems=0;
if (silent==2) {
silent=1;
no_cache_notice=1;
}
if (silent==3) {
silent=0;
no_cache_notice=1;
}
if (!silent) {
zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL);
zend_debug_alloc_output("---------------------------------------\n");
zend_debug_alloc_output("%s(%d) : Block 0x%0.8lX status:\n" ZEND_FILE_LINE_RELAY_CC, (long) p);
if (__zend_orig_filename) {
zend_debug_alloc_output("%s(%d) : Actual location (location was relayed)\n" ZEND_FILE_LINE_ORIG_RELAY_CC);
}
zend_debug_alloc_output("%10s\t","Beginning: ");
}
switch (p->magic) {
case MEM_BLOCK_START_MAGIC:
if (!silent) {
zend_debug_alloc_output("OK (allocated on %s:%d, %d bytes)\n", p->filename, p->lineno, p->size);
}
break; /* ok */
case MEM_BLOCK_FREED_MAGIC:
if (!silent) {
zend_debug_alloc_output("Freed\n");
had_problems=1;
} else {
return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
break;
case MEM_BLOCK_CACHED_MAGIC:
if (!silent) {
if (!no_cache_notice) {
zend_debug_alloc_output("Cached (allocated on %s:%d, %d bytes)\n", p->filename, p->lineno, p->size);
had_problems=1;
}
} else {
if (!no_cache_notice) {
return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
}
break;
default:
if (!silent) {
zend_debug_alloc_output("Overrun (magic=0x%0.8lX, expected=0x%0.8lX)\n", p->magic, MEM_BLOCK_START_MAGIC);
} else {
return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
had_problems=1;
valid_beginning=0;
break;
}
if (valid_beginning
&& *((long *)(((char *) p)+sizeof(zend_mem_header)+REAL_SIZE(p->size)+PLATFORM_PADDING+END_ALIGNMENT(REAL_SIZE(p->size)))) != MEM_BLOCK_END_MAGIC) {
long magic_num = MEM_BLOCK_END_MAGIC;
char *overflow_ptr, *magic_ptr=(char *) &magic_num;
int overflows=0;
int i;
if (silent) {
return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
had_problems=1;
overflow_ptr = ((char *) p)+sizeof(zend_mem_header)+REAL_SIZE(p->size)+PLATFORM_PADDING;
for (i=0; i<sizeof(long); i++) {
if (overflow_ptr[i]!=magic_ptr[i]) {
overflows++;
}
}
zend_debug_alloc_output("%10s\t", "End:");
zend_debug_alloc_output("Overflown (magic=0x%0.8lX instead of 0x%0.8lX)\n",
*((long *)(((char *) p) + sizeof(zend_mem_header)+REAL_SIZE(p->size)+PLATFORM_PADDING+END_ALIGNMENT(REAL_SIZE(p->size)))), MEM_BLOCK_END_MAGIC);
zend_debug_alloc_output("%10s\t","");
if (overflows>=sizeof(long)) {
zend_debug_alloc_output("At least %d bytes overflown\n", sizeof(long));
} else {
zend_debug_alloc_output("%d byte(s) overflown\n", overflows);
}
} else if (!silent) {
zend_debug_alloc_output("%10s\t", "End:");
if (valid_beginning) {
zend_debug_alloc_output("OK\n");
} else {
zend_debug_alloc_output("Unknown\n");
}
}
if (had_problems) {
int foo = 5;
foo+=1;
}
if (!silent) {
zend_debug_alloc_output("---------------------------------------\n");
}
return ((!had_problems) ? 1 : 0);
}
ZEND_API void _full_mem_check(int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p;
int errors=0;
ALS_FETCH();
p = AG(head);
zend_debug_alloc_output("------------------------------------------------\n");
zend_debug_alloc_output("Full Memory Check at %s:%d\n" ZEND_FILE_LINE_RELAY_CC);
while (p) {
if (!_mem_block_check((void *)((char *)p + sizeof(zend_mem_header) + PLATFORM_PADDING), (silent?2:3) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)) {
errors++;
}
p = p->pNext;
}
zend_debug_alloc_output("End of full memory check %s:%d (%d errors)\n" ZEND_FILE_LINE_RELAY_CC, errors);
zend_debug_alloc_output("------------------------------------------------\n");
}
#endif
ZEND_API int _persist_alloc(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mem_header *p = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-PLATFORM_PADDING);
ALS_FETCH();
#if ZEND_DEBUG
_mem_block_check(ptr, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#endif
HANDLE_BLOCK_INTERRUPTIONS();
/* remove the block from the non persistent list */
REMOVE_POINTER_FROM_LIST(p);
p->persistent = 1;
/* add the block to the persistent list */
ADD_POINTER_TO_LIST(p);
HANDLE_UNBLOCK_INTERRUPTIONS();
return REAL_SIZE(p->size)+sizeof(zend_mem_header)+PLATFORM_PADDING;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+136
View File
@@ -0,0 +1,136 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_ALLOC_H
#define ZEND_ALLOC_H
#include <stdio.h>
#include "zend_globals_macros.h"
#define MEM_BLOCK_START_MAGIC 0x7312F8DCL
#define MEM_BLOCK_END_MAGIC 0x2A8FCC84L
#define MEM_BLOCK_FREED_MAGIC 0x99954317L
#define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
typedef struct _zend_mem_header {
#if ZEND_DEBUG
long magic;
char *filename;
uint lineno;
int reported;
char *orig_filename;
uint orig_lineno;
#endif
struct _zend_mem_header *pNext;
struct _zend_mem_header *pLast;
unsigned int size:30;
unsigned int persistent:1;
unsigned int cached:1;
} zend_mem_header;
typedef union _align_test {
void *ptr;
double dbl;
long lng;
} align_test;
#define MAX_CACHED_MEMORY 11
#define MAX_CACHED_ENTRIES 256
#define PRE_INIT_CACHE_ENTRIES 32
#if (defined (__GNUC__) && __GNUC__ >= 2)
#define PLATFORM_ALIGNMENT (__alignof__ (align_test))
#else
#define PLATFORM_ALIGNMENT (sizeof(align_test))
#endif
#define PLATFORM_PADDING (((PLATFORM_ALIGNMENT-sizeof(zend_mem_header))%PLATFORM_ALIGNMENT+PLATFORM_ALIGNMENT)%PLATFORM_ALIGNMENT)
ZEND_API char *zend_strndup(const char *s, unsigned int length);
BEGIN_EXTERN_C()
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API int _persist_alloc(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
/* Standard wrapper macros */
#define emalloc(size) _emalloc((size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define efree(ptr) _efree((ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define ecalloc(nmemb,size) _ecalloc((nmemb), (size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc(ptr,size) _erealloc((ptr), (size),0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define erealloc_recoverable(ptr,size) _erealloc((ptr), (size),1 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define estrdup(s) _estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define estrndup(s,length) _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define persist_alloc(p) _persist_alloc((p) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
/* Relay wrapper macros */
#define emalloc_rel(size) _emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define efree_rel(ptr) _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define ecalloc_rel(nmemb, size) _ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define erealloc_rel(ptr, size) _erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define erealloc_recoverable_rel(ptr, size) _erealloc((ptr), (size), 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define estrdup_rel(s) _estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define estrndup_rel(s, length) _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
#define persist_alloc_rel(p) _persist_alloc((p) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
/* Selective persistent/non persistent allocation macros */
#define pemalloc(size,persistent) ((persistent)?malloc(size):emalloc(size))
#define pefree(ptr,persistent) ((persistent)?free(ptr):efree(ptr))
#define pecalloc(nmemb,size,persistent) ((persistent)?calloc((nmemb),(size)):ecalloc((nmemb),(size)))
#define perealloc(ptr,size,persistent) ((persistent)?realloc((ptr),(size)):erealloc((ptr),(size)))
#define perealloc_recoverable(ptr,size,persistent) ((persistent)?realloc((ptr),(size)):erealloc_recoverable((ptr),(size)))
#define pestrdup(s,persistent) ((persistent)?strdup(s):estrdup(s))
#define safe_estrdup(ptr) ((ptr)?(estrdup(ptr)):(empty_string))
#define safe_estrndup(ptr,len) ((ptr)?(estrndup((ptr),(len))):(empty_string))
ZEND_API int zend_set_memory_limit(unsigned int memory_limit);
ZEND_API void start_memory_manager(ALS_D);
ZEND_API void shutdown_memory_manager(int silent, int clean_cache);
#if ZEND_DEBUG
ZEND_API int _mem_block_check(void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void _full_mem_check(int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
void zend_debug_alloc_output(char *format, ...);
#define mem_block_check(ptr, silent) _mem_block_check(ptr, silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#define full_mem_check(silent) _full_mem_check(silent ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
#else
#define mem_block_check(type, ptr, silent)
#define full_mem_check(silent)
#endif
END_EXTERN_C()
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+943
View File
@@ -0,0 +1,943 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_API.h"
#include "zend_builtin_functions.h"
#include "zend_constants.h"
#undef ZEND_TEST_EXCEPTIONS
static ZEND_FUNCTION(zend_version);
static ZEND_FUNCTION(func_num_args);
static ZEND_FUNCTION(func_get_arg);
static ZEND_FUNCTION(func_get_args);
static ZEND_FUNCTION(strlen);
static ZEND_FUNCTION(strcmp);
static ZEND_FUNCTION(strncmp);
static ZEND_FUNCTION(strcasecmp);
static ZEND_FUNCTION(strncasecmp);
static ZEND_FUNCTION(each);
static ZEND_FUNCTION(error_reporting);
static ZEND_FUNCTION(define);
static ZEND_FUNCTION(defined);
static ZEND_FUNCTION(get_class);
static ZEND_FUNCTION(get_parent_class);
static ZEND_FUNCTION(method_exists);
static ZEND_FUNCTION(class_exists);
static ZEND_FUNCTION(function_exists);
static ZEND_FUNCTION(leak);
#ifdef ZEND_TEST_EXCEPTIONS
static ZEND_FUNCTION(crash);
#endif
static ZEND_FUNCTION(get_included_files);
static ZEND_FUNCTION(is_subclass_of);
static ZEND_FUNCTION(get_class_vars);
static ZEND_FUNCTION(get_object_vars);
static ZEND_FUNCTION(get_class_methods);
static ZEND_FUNCTION(trigger_error);
static ZEND_FUNCTION(set_error_handler);
static ZEND_FUNCTION(restore_error_handler);
static ZEND_FUNCTION(get_declared_classes);
static ZEND_FUNCTION(create_function);
static ZEND_FUNCTION(get_resource_type);
#if ZEND_DEBUG
static ZEND_FUNCTION(zend_test_func);
#endif
unsigned char first_arg_force_ref[] = { 1, BYREF_FORCE };
unsigned char first_arg_allow_ref[] = { 1, BYREF_ALLOW };
unsigned char second_arg_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };
unsigned char second_arg_allow_ref[] = { 2, BYREF_NONE, BYREF_ALLOW };
static zend_function_entry builtin_functions[] = {
ZEND_FE(zend_version, NULL)
ZEND_FE(func_num_args, NULL)
ZEND_FE(func_get_arg, NULL)
ZEND_FE(func_get_args, NULL)
ZEND_FE(strlen, NULL)
ZEND_FE(strcmp, NULL)
ZEND_FE(strncmp, NULL)
ZEND_FE(strcasecmp, NULL)
ZEND_FE(strncasecmp, NULL)
ZEND_FE(each, first_arg_force_ref)
ZEND_FE(error_reporting, NULL)
ZEND_FE(define, NULL)
ZEND_FE(defined, NULL)
ZEND_FE(get_class, NULL)
ZEND_FE(get_parent_class, NULL)
ZEND_FE(method_exists, NULL)
ZEND_FE(class_exists, NULL)
ZEND_FE(function_exists, NULL)
ZEND_FE(leak, NULL)
#ifdef ZEND_TEST_EXCEPTIONS
ZEND_FE(crash, NULL)
#endif
ZEND_FE(get_included_files, NULL)
ZEND_FALIAS(get_required_files, get_included_files, NULL)
ZEND_FE(is_subclass_of, NULL)
ZEND_FE(get_class_vars, NULL)
ZEND_FE(get_object_vars, NULL)
ZEND_FE(get_class_methods, NULL)
ZEND_FE(trigger_error, NULL)
ZEND_FALIAS(user_error, trigger_error, NULL)
ZEND_FE(set_error_handler, NULL)
ZEND_FE(restore_error_handler, NULL)
ZEND_FE(get_declared_classes, NULL)
ZEND_FE(create_function, NULL)
ZEND_FE(get_resource_type, NULL)
#if ZEND_DEBUG
ZEND_FE(zend_test_func, NULL)
#endif
{ NULL, NULL, NULL }
};
int zend_startup_builtin_functions()
{
return zend_register_functions(builtin_functions, NULL, MODULE_PERSISTENT);
}
ZEND_FUNCTION(zend_version)
{
RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
}
ZEND_FUNCTION(func_num_args)
{
void **p;
int arg_count;
p = EG(argument_stack).top_element-1-1;
arg_count = (ulong) *p; /* this is the amount of arguments passed to func_num_args(); */
p -= 1+arg_count;
if (*p) {
zend_error(E_ERROR, "func_num_args(): Can't be used as a function parameter");
}
--p;
if (p>=EG(argument_stack).elements) {
RETURN_LONG((ulong) *p);
} else {
zend_error(E_WARNING, "func_num_args(): Called from the global scope - no function context");
RETURN_LONG(-1);
}
}
ZEND_FUNCTION(func_get_arg)
{
void **p;
int arg_count;
zval **z_requested_offset;
zval *arg;
long requested_offset;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &z_requested_offset)==FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(z_requested_offset);
requested_offset = (*z_requested_offset)->value.lval;
p = EG(argument_stack).top_element-1-1;
arg_count = (ulong) *p; /* this is the amount of arguments passed to func_get_arg(); */
p -= 1+arg_count;
if (*p) {
zend_error(E_ERROR, "func_get_arg(): Can't be used as a function parameter");
}
--p;
if (p<EG(argument_stack).elements) {
zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
RETURN_FALSE;
}
arg_count = (ulong) *p;
if (requested_offset>=arg_count) {
zend_error(E_WARNING, "func_get_arg(): Argument %d not passed to function", requested_offset);
RETURN_FALSE;
}
arg = *(p-(arg_count-requested_offset));
*return_value = *arg;
zval_copy_ctor(return_value);
}
ZEND_FUNCTION(func_get_args)
{
void **p;
int arg_count;
int i;
p = EG(argument_stack).top_element-1-1;
arg_count = (ulong) *p; /* this is the amount of arguments passed to func_get_args(); */
p -= 1+arg_count;
if (*p) {
zend_error(E_ERROR, "func_get_args(): Can't be used as a function parameter");
}
--p;
if (p<EG(argument_stack).elements) {
zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
RETURN_FALSE;
}
arg_count = (ulong) *p;
array_init(return_value);
for (i=0; i<arg_count; i++) {
zval *element;
ALLOC_ZVAL(element);
*element = **((zval **) (p-(arg_count-i)));
zval_copy_ctor(element);
INIT_PZVAL(element);
zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
}
}
/* {{{ proto int strlen(string str)
Get string length */
ZEND_FUNCTION(strlen)
{
zval **str;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(str);
RETVAL_LONG((*str)->value.str.len);
}
/* }}} */
/* {{{ proto int strcmp(string str1, string str2)
Binary safe string comparison */
ZEND_FUNCTION(strcmp)
{
zval **s1, **s2;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(s1);
convert_to_string_ex(s2);
RETURN_LONG(zend_binary_zval_strcmp(*s1,*s2));
}
/* }}} */
/* {{{ proto int strncmp(string str1, string str2, int len)
Binary safe string comparison */
ZEND_FUNCTION(strncmp)
{
zval **s1, **s2, **s3;
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &s1, &s2, &s3) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(s1);
convert_to_string_ex(s2);
convert_to_long_ex(s3);
RETURN_LONG(zend_binary_zval_strncmp(*s1,*s2,*s3));
}
/* }}} */
/* {{{ proto int strcasecmp(string str1, string str2)
Binary safe case-insensitive string comparison */
ZEND_FUNCTION(strcasecmp)
{
zval **s1, **s2;
if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(s1);
convert_to_string_ex(s2);
RETURN_LONG(zend_binary_zval_strcasecmp(*s1, *s2));
}
/* }}} */
/* {{{ proto int strncasecmp(string str1, string str2, int len)
Binary safe string comparison */
ZEND_FUNCTION(strncasecmp)
{
zval **s1, **s2, **s3;
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &s1, &s2, &s3) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(s1);
convert_to_string_ex(s2);
convert_to_long_ex(s3);
RETURN_LONG(zend_binary_zval_strncasecmp(*s1,*s2,*s3));
}
/* }}} */
ZEND_FUNCTION(each)
{
zval **array,*entry,**entry_ptr, *tmp;
char *string_key;
ulong num_key;
zval **inserted_pointer;
HashTable *target_hash;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &array) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
target_hash = HASH_OF(*array);
if (!target_hash) {
zend_error(E_WARNING,"Variable passed to each() is not an array or object");
return;
}
if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
RETURN_FALSE;
}
array_init(return_value);
entry = *entry_ptr;
/* add value elements */
if (entry->is_ref) {
ALLOC_ZVAL(tmp);
*tmp = *entry;
zval_copy_ctor(tmp);
tmp->is_ref=0;
tmp->refcount=0;
entry=tmp;
}
zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
entry->refcount++;
zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
entry->refcount++;
/* add the key elements */
switch (zend_hash_get_current_key(target_hash, &string_key, &num_key)) {
case HASH_KEY_IS_STRING:
add_get_index_string(return_value,0,string_key,(void **) &inserted_pointer,0);
break;
case HASH_KEY_IS_LONG:
add_get_index_long(return_value,0,num_key, (void **) &inserted_pointer);
break;
}
zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
(*inserted_pointer)->refcount++;
zend_hash_move_forward(target_hash);
}
ZEND_FUNCTION(error_reporting)
{
zval **arg;
int old_error_reporting;
old_error_reporting = EG(error_reporting);
switch (ZEND_NUM_ARGS()) {
case 0:
break;
case 1:
if (zend_get_parameters_ex(1,&arg) == FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(arg);
EG(error_reporting)=(*arg)->value.lval;
break;
default:
ZEND_WRONG_PARAM_COUNT();
break;
}
RETVAL_LONG(old_error_reporting);
}
ZEND_FUNCTION(define)
{
zval **var, **val, **non_cs;
int case_sensitive;
zend_constant c;
switch(ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &var, &val)==FAILURE) {
RETURN_FALSE;
}
case_sensitive = CONST_CS;
break;
case 3:
if (zend_get_parameters_ex(3, &var, &val, &non_cs)==FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(non_cs);
if ((*non_cs)->value.lval) {
case_sensitive = 0;
} else {
case_sensitive = CONST_CS;
}
break;
default:
ZEND_WRONG_PARAM_COUNT();
break;
}
switch((*val)->type) {
case IS_LONG:
case IS_DOUBLE:
case IS_STRING:
case IS_BOOL:
case IS_RESOURCE:
case IS_NULL:
break;
default:
zend_error(E_WARNING,"Constants may only evaluate to scalar values");
RETURN_FALSE;
break;
}
convert_to_string_ex(var);
c.value = **val;
zval_copy_ctor(&c.value);
c.flags = case_sensitive; /* non persistent */
c.name = zend_strndup((*var)->value.str.val, (*var)->value.str.len);
c.name_len = (*var)->value.str.len+1;
if(zend_register_constant(&c ELS_CC) == SUCCESS) {
RETURN_TRUE;
} else {
RETURN_FALSE;
}
}
ZEND_FUNCTION(defined)
{
zval **var;
zval c;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &var)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(var);
if (zend_get_constant((*var)->value.str.val, (*var)->value.str.len, &c)) {
zval_dtor(&c);
RETURN_LONG(1);
} else {
RETURN_LONG(0);
}
}
/* {{{ proto string get_class(object object)
Retrieves the class name */
ZEND_FUNCTION(get_class)
{
zval **arg;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if ((*arg)->type != IS_OBJECT) {
RETURN_FALSE;
}
RETURN_STRINGL((*arg)->value.obj.ce->name, (*arg)->value.obj.ce->name_length, 1);
}
/* }}} */
/* {{{ proto string get_parent_class(object object)
Retrieves the parent class name */
ZEND_FUNCTION(get_parent_class)
{
zval **arg;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if (((*arg)->type != IS_OBJECT) || !(*arg)->value.obj.ce->parent) {
RETURN_FALSE;
}
RETURN_STRINGL((*arg)->value.obj.ce->parent->name, (*arg)->value.obj.ce->parent->name_length, 1);
}
/* }}} */
/* {{{ proto bool is_subclass_of(object object, string class_name)
Returns true if the object has this class as one of its parents */
ZEND_FUNCTION(is_subclass_of)
{
zval **obj, **class_name;
char *lcname;
zend_class_entry *parent_ce = NULL;
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &obj, &class_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if ((*obj)->type != IS_OBJECT) {
RETURN_FALSE;
}
convert_to_string_ex(class_name);
lcname = estrndup((*class_name)->value.str.val, (*class_name)->value.str.len);
zend_str_tolower(lcname, (*class_name)->value.str.len);
for (parent_ce = (*obj)->value.obj.ce->parent; parent_ce != NULL; parent_ce = parent_ce->parent) {
if (!strcmp(parent_ce->name, lcname)) {
efree(lcname);
RETURN_TRUE;
}
}
efree(lcname);
RETURN_FALSE;
}
/* }}} */
/* {{{ proto array get_class_vars(string class_name)
Returns an array of default properties of the class */
ZEND_FUNCTION(get_class_vars)
{
zval **class_name;
char *lcname;
zend_class_entry *ce;
zval *tmp;
CLS_FETCH();
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(class_name);
lcname = estrndup((*class_name)->value.str.val, (*class_name)->value.str.len);
zend_str_tolower(lcname, (*class_name)->value.str.len);
if (zend_hash_find(CG(class_table), lcname, (*class_name)->value.str.len+1, (void **)&ce)==FAILURE) {
efree(lcname);
RETURN_FALSE;
} else {
efree(lcname);
array_init(return_value);
zend_hash_copy(return_value->value.ht, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
}
}
/* }}} */
/* {{{ proto array get_object_vars(object obj)
Returns an array of object properties */
ZEND_FUNCTION(get_object_vars)
{
zval **obj;
zval *tmp;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &obj) == FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if ((*obj)->type != IS_OBJECT) {
RETURN_FALSE;
}
array_init(return_value);
zend_hash_copy(return_value->value.ht, (*obj)->value.obj.properties,
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
}
/* }}} */
/* {{{ proto array get_class_methods(string class_name)
Returns an array of class methods' names */
ZEND_FUNCTION(get_class_methods)
{
zval **class_name;
zval *method_name;
char *lcname;
zend_class_entry *ce;
char *string_key;
ulong num_key;
int key_type;
CLS_FETCH();
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(class_name);
lcname = estrndup((*class_name)->value.str.val, (*class_name)->value.str.len);
zend_str_tolower(lcname, (*class_name)->value.str.len);
if (zend_hash_find(CG(class_table), lcname, (*class_name)->value.str.len+1, (void **)&ce)==FAILURE) {
efree(lcname);
RETURN_NULL();
} else {
efree(lcname);
array_init(return_value);
zend_hash_internal_pointer_reset(&ce->function_table);
while ((key_type = zend_hash_get_current_key(&ce->function_table, &string_key, &num_key)) != HASH_KEY_NON_EXISTANT) {
if (key_type == HASH_KEY_IS_STRING) {
MAKE_STD_ZVAL(method_name);
ZVAL_STRING(method_name, string_key, 1);
zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
}
zend_hash_move_forward(&ce->function_table);
}
}
}
/* }}} */
/* {{{ proto bool method_exists(object object, string method)
Checks if the class method exists */
ZEND_FUNCTION(method_exists)
{
zval **klass, **method_name;
char *lcname;
if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &klass, &method_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if ((*klass)->type != IS_OBJECT) {
RETURN_FALSE;
}
convert_to_string_ex(method_name);
lcname = estrndup((*method_name)->value.str.val, (*method_name)->value.str.len);
zend_str_tolower(lcname, (*method_name)->value.str.len);
if(zend_hash_exists(&(*klass)->value.obj.ce->function_table, lcname, (*method_name)->value.str.len+1)) {
efree(lcname);
RETURN_TRUE;
} else {
efree(lcname);
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto bool class_exists(string classname)
Checks if the class exists */
ZEND_FUNCTION(class_exists)
{
zval **class_name;
char *lcname;
CLS_FETCH();
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(class_name);
lcname = estrndup((*class_name)->value.str.val, (*class_name)->value.str.len);
zend_str_tolower(lcname, (*class_name)->value.str.len);
if (zend_hash_exists(CG(class_table), lcname, (*class_name)->value.str.len+1)) {
efree(lcname);
RETURN_TRUE;
} else {
efree(lcname);
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto bool function_exists(string function_name)
Checks if the function exists */
ZEND_FUNCTION(function_exists)
{
zval **function_name;
char *lcname;
int retval;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(function_name);
lcname = estrndup((*function_name)->value.str.val, (*function_name)->value.str.len);
zend_str_tolower(lcname, (*function_name)->value.str.len);
retval = zend_hash_exists(EG(function_table), lcname, (*function_name)->value.str.len+1);
efree(lcname);
RETURN_BOOL(retval);
}
/* }}} */
ZEND_FUNCTION(leak)
{
int leakbytes=3;
zval **leak;
if (ZEND_NUM_ARGS()>=1) {
if (zend_get_parameters_ex(1, &leak)==SUCCESS) {
convert_to_long_ex(leak);
leakbytes = (*leak)->value.lval;
}
}
emalloc(leakbytes);
}
#ifdef ZEND_TEST_EXCEPTIONS
ZEND_FUNCTION(crash)
{
char *nowhere=NULL;
memcpy(nowhere, "something", sizeof("something"));
}
#endif
static int copy_import_use_file(zend_file_handle *fh, zval *array)
{
if (fh->filename) {
char *extension_start;
extension_start = strstr(fh->filename, zend_uv.import_use_extension);
if (extension_start) {
*extension_start = 0;
if (fh->opened_path) {
add_assoc_string(array, fh->filename, fh->opened_path, 1);
} else {
add_assoc_stringl(array, fh->filename, "N/A", sizeof("N/A")-1, 1);
}
*extension_start = zend_uv.import_use_extension[0];
}
}
return 0;
}
/* {{{ proto array get_included_files(void)
Returns an array with the file names that were include_once()'d */
ZEND_FUNCTION(get_included_files)
{
char *entry;
if (ZEND_NUM_ARGS() != 0) {
ZEND_WRONG_PARAM_COUNT();
}
array_init(return_value);
zend_hash_internal_pointer_reset(&EG(included_files));
while(zend_hash_get_current_key(&EG(included_files), &entry,NULL) == HASH_KEY_IS_STRING) {
add_next_index_string(return_value,entry,0);
zend_hash_move_forward(&EG(included_files));
}
/* zend_hash_apply_with_argument(&EG(included_files), (apply_func_arg_t) copy_import_use_file, return_value); */
}
/* }}} */
/* {{{ proto void trigger_error(string messsage [, int error_type])
Generates a user-level error/warning/notice message */
ZEND_FUNCTION(trigger_error)
{
int error_type = E_USER_NOTICE;
zval **z_error_type, **z_error_message;
switch(ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &z_error_message)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
break;
case 2:
if (zend_get_parameters_ex(2, &z_error_message, &z_error_type)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_long_ex(z_error_type);
error_type = (*z_error_type)->value.lval;
switch (error_type) {
case E_USER_ERROR:
case E_USER_WARNING:
case E_USER_NOTICE:
break;
default:
zend_error(E_WARNING, "Invalid error type specified");
RETURN_FALSE;
break;
}
break;
default:
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(z_error_message);
zend_error(error_type, "%s", (*z_error_message)->value.str.val);
RETURN_TRUE;
}
/* }}} */
/* {{{ proto string set_error_handler(string error_handler)
Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
ZEND_FUNCTION(set_error_handler)
{
zval **error_handler;
zend_bool had_orig_error_handler=0;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &error_handler)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(error_handler);
if (EG(user_error_handler)) {
had_orig_error_handler = 1;
*return_value = *EG(user_error_handler);
zval_copy_ctor(return_value);
zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
}
ALLOC_ZVAL(EG(user_error_handler));
if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined handler */
FREE_ZVAL(EG(user_error_handler));
EG(user_error_handler) = NULL;
RETURN_TRUE;
}
*EG(user_error_handler) = **error_handler;
zval_copy_ctor(EG(user_error_handler));
if (!had_orig_error_handler) {
RETURN_NULL();
}
}
/* }}} */
/* {{{ proto void restore_error_handler(void)
Restores the previously defined error handler function */
ZEND_FUNCTION(restore_error_handler)
{
if (EG(user_error_handler)) {
zval_ptr_dtor(&EG(user_error_handler));
}
if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
EG(user_error_handler) = NULL;
} else {
EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
}
RETURN_TRUE;
}
static int copy_class_name(zend_class_entry *ce, int num_args, va_list args, zend_hash_key *hash_key)
{
zval *array = va_arg(args, zval *);
if (hash_key->nKeyLength==0 || hash_key->arKey[0]!=0) {
add_next_index_stringl(array, ce->name, ce->name_length, 1);
}
return 0;
}
/* {{{ proto array get_declared_classes(void)
Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)
{
CLS_FETCH();
if (ZEND_NUM_ARGS() != 0) {
ZEND_WRONG_PARAM_COUNT();
}
array_init(return_value);
zend_hash_apply_with_arguments(CG(class_table), (apply_func_args_t)copy_class_name, 1, return_value);
}
/* }}} */
#define LAMBDA_TEMP_FUNCNAME "__lambda_func"
/* {{{ proto string create_function(string args, string code)
Creates an anonymous function, and returns its name (funny, eh?) */
ZEND_FUNCTION(create_function)
{
char *eval_code, *function_name;
int eval_code_length, function_name_length;
zval **z_function_args, **z_function_code;
int retval;
char *eval_name;
CLS_FETCH();
if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &z_function_args, &z_function_code)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
convert_to_string_ex(z_function_args);
convert_to_string_ex(z_function_code);
eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME)
+Z_STRLEN_PP(z_function_args)
+2 /* for the args parentheses */
+2 /* for the curly braces */
+Z_STRLEN_PP(z_function_code);
eval_code = (char *) emalloc(eval_code_length);
sprintf(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(%s){%s}", Z_STRVAL_PP(z_function_args), Z_STRVAL_PP(z_function_code));
eval_name = zend_make_compiled_string_description("runtime-created function");
retval = zend_eval_string(eval_code, NULL, eval_name CLS_CC ELS_CC);
efree(eval_code);
efree(eval_name);
if (retval==SUCCESS) {
zend_function *func;
if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
RETURN_FALSE;
}
function_add_ref(func);
function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
do {
sprintf(function_name, "%clambda_%d", 0, ++EG(lambda_count));
function_name_length = strlen(function_name+1)+1;
} while (zend_hash_add(EG(function_table), function_name, function_name_length+1, func, sizeof(zend_function), NULL)==FAILURE);
zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
RETURN_STRINGL(function_name, function_name_length, 0);
} else {
RETURN_FALSE;
}
}
/* }}} */
#if ZEND_DEBUG
ZEND_FUNCTION(zend_test_func)
{
zval *arg1, *arg2;
zend_get_parameters(ht, 2, &arg1, &arg2);
}
#endif
ZEND_FUNCTION(get_resource_type)
{
char *resource_type;
zval **z_resource_type;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &z_resource_type)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
if (Z_TYPE_PP(z_resource_type) != IS_RESOURCE) {
zend_error(E_WARNING, "Supplied argument is not a valid resource handle");
RETURN_FALSE;
}
resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(z_resource_type));
if (resource_type) {
RETURN_STRING(resource_type, 1);
} else {
RETURN_STRING("Unknown", 1);
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_BUILTIN_FUNCTIONS_H
#define ZEND_BUILTIN_FUNCTIONS_H
int zend_startup_builtin_functions(void);
#endif /* ZEND_BUILTIN_FUNCTIONS_H */
+2349
View File
File diff suppressed because it is too large. Load diff
+629
View File
@@ -0,0 +1,629 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_COMPILE_H
#define ZEND_COMPILE_H
#include "zend.h"
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
#ifdef __cplusplus
#include <istream.h>
#endif
#include "zend_llist.h"
#define DEBUG_ZEND 0
#ifndef ZTS
# define SUPPORT_INTERACTIVE 1
#else
# define SUPPORT_INTERACTIVE 0
#endif
#define FREE_PNODE(znode) zval_dtor(&znode->u.constant);
#define FREE_OP(op, should_free) if (should_free) zval_dtor(&Ts[(op)->u.var].tmp_var);
#if SUPPORT_INTERACTIVE
#define INC_BPC(op_array) ((op_array)->backpatch_count++)
#define DEC_BPC(op_array) ((op_array)->backpatch_count--)
#define HANDLE_INTERACTIVE() if (EG(interactive)) { execute_new_code(CLS_C); }
#else
#define INC_BPC(op_array)
#define DEC_BPC(op_array)
#define HANDLE_INTERACTIVE()
#endif
typedef struct _zend_op_array zend_op_array;
typedef struct _znode {
int op_type;
union {
zval constant;
zend_uint var;
zend_uint opline_num; /* Needs to be signed */
zend_uint fetch_type;
zend_op_array *op_array;
struct {
zend_uint var; /* dummy */
zend_uint type;
} EA;
} u;
} znode;
typedef struct _zend_op {
zend_uchar opcode;
znode result;
znode op1;
znode op2;
ulong extended_value;
uint lineno;
} zend_op;
typedef struct _zend_brk_cont_element {
int cont;
int brk;
int parent;
} zend_brk_cont_element;
struct _zend_op_array {
zend_uchar type; /* MUST be the first element of this struct! */
zend_uchar *arg_types; /* MUST be the second element of this struct! */
char *function_name; /* MUST be the third element of this struct! */
zend_uint *refcount;
zend_op *opcodes;
zend_uint last, size;
zend_uint T;
zend_brk_cont_element *brk_cont_array;
zend_uint last_brk_cont;
zend_uint current_brk_cont;
zend_bool uses_globals;
/* static variables support */
HashTable *static_variables;
#if SUPPORT_INTERACTIVE
int start_op_number, end_op_number;
int last_executed_op_number;
int backpatch_count;
#endif
zend_bool return_reference;
zend_bool done_pass_two;
char *filename;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};
typedef struct _zend_internal_function {
zend_uchar type; /* MUST be the first element of this struct! */
zend_uchar *arg_types; /* MUST be the second element of this struct */
char *function_name; /* MUST be the third element of this struct */
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
} zend_internal_function;
typedef struct _zend_overloaded_function {
zend_uchar type; /* MUST be the first element of this struct! */
zend_uchar *arg_types; /* MUST be the second element of this struct */
char *function_name; /* MUST be the third element of this struct */
zend_uint var;
} zend_overloaded_function;
typedef union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
zend_uchar *arg_types;
char *function_name;
} common;
zend_op_array op_array;
zend_internal_function internal_function;
zend_overloaded_function overloaded_function;
} zend_function;
typedef struct _zend_function_state {
HashTable *function_symbol_table;
zend_function *function;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
} zend_function_state;
typedef struct _zend_switch_entry {
znode cond;
int default_case;
int control_var;
} zend_switch_entry;
typedef struct _list_llist_element {
znode var;
zend_llist dimensions;
znode value;
} list_llist_element;
typedef struct _zend_file_handle {
zend_uchar type;
char *filename;
char *opened_path;
union {
int fd;
FILE *fp;
#ifdef __cplusplus
istream *is;
#endif
} handle;
zend_bool free_filename;
} zend_file_handle;
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
#define IS_VAR (1<<2)
#define IS_UNUSED (1<<3) /* Unused variable */
#define EXT_TYPE_UNUSED (1<<0)
#include "zend_globals.h"
BEGIN_EXTERN_C()
void init_compiler(CLS_D ELS_DC);
void shutdown_compiler(CLS_D);
extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type CLS_DC);
void zend_activate(CLS_D ELS_DC);
void zend_deactivate(CLS_D ELS_DC);
void zend_activate_modules(void);
void zend_deactivate_modules(void);
int lex_scan(zval *zendlval CLS_DC);
void startup_scanner(CLS_D);
void shutdown_scanner(CLS_D);
ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename);
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename);
ZEND_API char *zend_get_compiled_filename(CLS_D);
ZEND_API int zend_get_compiled_lineno(CLS_D);
#ifdef ZTS
const char *zend_get_zendtext(CLS_D);
int zend_get_zendleng(CLS_D);
#endif
/* parser-driven code generators */
void do_binary_op(int op, znode *result, znode *op1, znode *op2 CLS_DC);
void do_unary_op(int op, znode *result, znode *op1 CLS_DC);
void do_binary_assign_op(int op, znode *result, znode *op1, znode *op2 CLS_DC);
void do_assign(znode *result, znode *variable, znode *value CLS_DC);
void do_assign_ref(znode *result, znode *lvar, znode *rvar CLS_DC);
void fetch_simple_variable(znode *result, znode *varname, int bp CLS_DC);
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, int op CLS_DC);
void do_indirect_references(znode *result, znode *num_references, znode *variable CLS_DC);
void do_fetch_global_or_static_variable(znode *varname, znode *static_assignment, int fetch_type CLS_DC);
void do_fetch_globals(znode *varname CLS_DC);
void fetch_array_begin(znode *result, znode *varname, znode *first_dim CLS_DC);
void fetch_array_dim(znode *result, znode *parent, znode *dim CLS_DC);
void fetch_string_offset(znode *result, znode *parent, znode *offset CLS_DC);
void do_print(znode *result, znode *arg CLS_DC);
void do_echo(znode *arg CLS_DC);
typedef int (*unary_op_type)(zval *, zval *);
ZEND_API unary_op_type get_unary_op(int opcode);
ZEND_API void *get_binary_op(int opcode);
void do_while_cond(znode *expr, znode *close_bracket_token CLS_DC);
void do_while_end(znode *while_token, znode *close_bracket_token CLS_DC);
void do_do_while_begin(CLS_D);
void do_do_while_end(znode *do_token, znode *expr_open_bracket, znode *expr CLS_DC);
void do_if_cond(znode *cond, znode *closing_bracket_token CLS_DC);
void do_if_after_statement(znode *closing_bracket_token, unsigned char initialize CLS_DC);
void do_if_end(CLS_D);
void do_for_cond(znode *expr, znode *second_semicolon_token CLS_DC);
void do_for_before_statement(znode *cond_start, znode *second_semicolon_token CLS_DC);
void do_for_end(znode *second_semicolon_token CLS_DC);
void do_pre_incdec(znode *result, znode *op1, int op CLS_DC);
void do_post_incdec(znode *result, znode *op1, int op CLS_DC);
void do_begin_variable_parse(CLS_D);
void do_end_variable_parse(int type, int arg_offset CLS_DC);
void do_free(znode *op1 CLS_DC);
void do_init_string(znode *result CLS_DC);
void do_add_char(znode *result, znode *op1, znode *op2 CLS_DC);
void do_add_string(znode *result, znode *op1, znode *op2 CLS_DC);
void do_add_variable(znode *result, znode *op1, znode *op2 CLS_DC);
void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference CLS_DC);
void do_end_function_declaration(znode *function_token CLS_DC);
void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, unsigned char pass_type CLS_DC);
int do_begin_function_call(znode *function_name CLS_DC);
void do_begin_dynamic_function_call(znode *function_name CLS_DC);
void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
void do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall CLS_DC);
void do_return(znode *expr, int do_end_vparse CLS_DC);
ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_table, HashTable *class_table, int compile_time);
void do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce);
void do_early_binding(CLS_D);
void do_pass_param(znode *param, int op, int offset CLS_DC);
void do_boolean_or_begin(znode *expr1, znode *op_token CLS_DC);
void do_boolean_or_end(znode *result, znode *expr1, znode *expr2, znode *op_token CLS_DC);
void do_boolean_and_begin(znode *expr1, znode *op_token CLS_DC);
void do_boolean_and_end(znode *result, znode *expr1, znode *expr2, znode *op_token CLS_DC);
void do_brk_cont(int op, znode *expr CLS_DC);
void do_switch_cond(znode *cond CLS_DC);
void do_switch_end(znode *case_list CLS_DC);
void do_case_before_statement(znode *case_list, znode *case_token, znode *case_expr CLS_DC);
void do_case_after_statement(znode *result, znode *case_token CLS_DC);
void do_default_before_statement(znode *case_list, znode *default_token CLS_DC);
void do_begin_class_declaration(znode *class_name, znode *parent_class_name CLS_DC);
void do_end_class_declaration(CLS_D);
void do_declare_property(znode *var_name, znode *value CLS_DC);
void do_fetch_property(znode *result, znode *object, znode *property CLS_DC);
void do_push_object(znode *object CLS_DC);
void do_pop_object(znode *object CLS_DC);
void do_begin_new_object(znode *new_token, znode *class_name CLS_DC);
void do_end_new_object(znode *result, znode *class_name, znode *new_token, znode *argument_list CLS_DC);
void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC);
void do_shell_exec(znode *result, znode *cmd CLS_DC);
void do_init_array(znode *result, znode *expr, znode *offset, int is_ref CLS_DC);
void do_add_array_element(znode *result, znode *expr, znode *offset, int is_ref CLS_DC);
void do_add_static_array_element(znode *result, znode *offset, znode *expr);
void do_list_init(CLS_D);
void do_list_end(znode *result, znode *expr CLS_DC);
void do_add_list_element(znode *element CLS_DC);
void do_new_list_begin(CLS_D);
void do_new_list_end(CLS_D);
void do_cast(znode *result, znode *expr, int type CLS_DC);
void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC);
void do_unset(znode *variable CLS_DC);
void do_isset_or_isempty(int type, znode *result, znode *variable CLS_DC);
void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token, int variable CLS_DC);
void do_foreach_cont(znode *value, znode *key, znode *as_token CLS_DC);
void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC);
void do_declare_begin(CLS_D);
void do_declare_stmt(znode *var, znode *val CLS_DC);
void do_declare_end(CLS_D);
void do_end_heredoc(CLS_D);
void do_exit(znode *result, znode *message CLS_DC);
void do_begin_silence(znode *strudel_token CLS_DC);
void do_end_silence(znode *strudel_token CLS_DC);
void do_begin_qm_op(znode *cond, znode *qm_token CLS_DC);
void do_qm_true(znode *true_value, znode *qm_token, znode *colon_token CLS_DC);
void do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colon_token CLS_DC);
void do_extended_info(CLS_D);
void do_extended_fcall_begin(CLS_D);
void do_extended_fcall_end(CLS_D);
void do_ticks(CLS_D);
ZEND_API void function_add_ref(zend_function *function);
#define INITIAL_OP_ARRAY_SIZE 64
/* helper functions in zend-scanner.l */
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type CLS_DC);
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename CLS_DC);
ZEND_API zend_op_array *compile_filename(int type, zval *filename CLS_DC ELS_DC);
ZEND_API int zend_execute_scripts(int type CLS_DC ELS_DC, int file_count, ...);
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
ZEND_API void init_op_array(zend_op_array *op_array, int type, int initial_ops_size CLS_DC);
ZEND_API void destroy_op_array(zend_op_array *op_array);
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle CLS_DC);
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh);
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void destroy_zend_class(zend_class_entry *ce);
void zend_class_add_ref(zend_class_entry *ce);
#define ZEND_FUNCTION_DTOR (void (*)(void *)) destroy_zend_function
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
zend_op *get_next_op(zend_op_array *op_array CLS_DC);
void init_op(zend_op *op CLS_DC);
int get_next_op_number(zend_op_array *op_array);
int print_class(zend_class_entry *class_entry);
void print_op_array(zend_op_array *op_array, int optimizations);
int pass_two(zend_op_array *op_array);
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
ZEND_API zend_bool zend_is_compiling(void);
ZEND_API char *zend_make_compiled_string_description(char *name);
int zendlex(znode *zendlval CLS_DC);
#define ZEND_NOP 0
#define ZEND_ADD 1
#define ZEND_SUB 2
#define ZEND_MUL 3
#define ZEND_DIV 4
#define ZEND_MOD 5
#define ZEND_SL 6
#define ZEND_SR 7
#define ZEND_CONCAT 8
#define ZEND_BW_OR 9
#define ZEND_BW_AND 10
#define ZEND_BW_XOR 11
#define ZEND_BW_NOT 12
#define ZEND_BOOL_NOT 13
#define ZEND_BOOL_XOR 14
#define ZEND_IS_IDENTICAL 15
#define ZEND_IS_NOT_IDENTICAL 16
#define ZEND_IS_EQUAL 17
#define ZEND_IS_NOT_EQUAL 18
#define ZEND_IS_SMALLER 19
#define ZEND_IS_SMALLER_OR_EQUAL 20
#define ZEND_CAST 21
#define ZEND_QM_ASSIGN 22
#define ZEND_ASSIGN_ADD 23
#define ZEND_ASSIGN_SUB 24
#define ZEND_ASSIGN_MUL 25
#define ZEND_ASSIGN_DIV 26
#define ZEND_ASSIGN_MOD 27
#define ZEND_ASSIGN_SL 28
#define ZEND_ASSIGN_SR 29
#define ZEND_ASSIGN_CONCAT 30
#define ZEND_ASSIGN_BW_OR 31
#define ZEND_ASSIGN_BW_AND 32
#define ZEND_ASSIGN_BW_XOR 33
#define ZEND_PRE_INC 34
#define ZEND_PRE_DEC 35
#define ZEND_POST_INC 36
#define ZEND_POST_DEC 37
#define ZEND_ASSIGN 38
#define ZEND_ASSIGN_REF 39
#define ZEND_ECHO 40
#define ZEND_PRINT 41
#define ZEND_JMP 42
#define ZEND_JMPZ 43
#define ZEND_JMPNZ 44
#define ZEND_JMPZNZ 45
#define ZEND_JMPZ_EX 46
#define ZEND_JMPNZ_EX 47
#define ZEND_CASE 48
#define ZEND_SWITCH_FREE 49
#define ZEND_BRK 50
#define ZEND_CONT 51
#define ZEND_BOOL 52
#define ZEND_INIT_STRING 53
#define ZEND_ADD_CHAR 54
#define ZEND_ADD_STRING 55
#define ZEND_ADD_VAR 56
#define ZEND_BEGIN_SILENCE 57
#define ZEND_END_SILENCE 58
#define ZEND_INIT_FCALL_BY_NAME 59
#define ZEND_DO_FCALL 60
#define ZEND_DO_FCALL_BY_NAME 61
#define ZEND_RETURN 62
#define ZEND_RECV 63
#define ZEND_RECV_INIT 64
#define ZEND_SEND_VAL 65
#define ZEND_SEND_VAR 66
#define ZEND_SEND_REF 67
#define ZEND_NEW 68
#define ZEND_JMP_NO_CTOR 69
#define ZEND_FREE 70
#define ZEND_INIT_ARRAY 71
#define ZEND_ADD_ARRAY_ELEMENT 72
#define ZEND_INCLUDE_OR_EVAL 73
#define ZEND_UNSET_VAR 74
#define ZEND_UNSET_DIM_OBJ 75
#define ZEND_ISSET_ISEMPTY 76
#define ZEND_FE_RESET 77
#define ZEND_FE_FETCH 78
#define ZEND_EXIT 79
/* the following 18 opcodes are 6 groups of 3 opcodes each, and must
* remain in that order!
*/
#define ZEND_FETCH_R 80
#define ZEND_FETCH_DIM_R 81
#define ZEND_FETCH_OBJ_R 82
#define ZEND_FETCH_W 83
#define ZEND_FETCH_DIM_W 84
#define ZEND_FETCH_OBJ_W 85
#define ZEND_FETCH_RW 86
#define ZEND_FETCH_DIM_RW 87
#define ZEND_FETCH_OBJ_RW 88
#define ZEND_FETCH_IS 89
#define ZEND_FETCH_DIM_IS 90
#define ZEND_FETCH_OBJ_IS 91
#define ZEND_FETCH_FUNC_ARG 92
#define ZEND_FETCH_DIM_FUNC_ARG 93
#define ZEND_FETCH_OBJ_FUNC_ARG 94
#define ZEND_FETCH_UNSET 95
#define ZEND_FETCH_DIM_UNSET 96
#define ZEND_FETCH_OBJ_UNSET 97
#define ZEND_FETCH_DIM_TMP_VAR 98
#define ZEND_FETCH_CONSTANT 99
#define ZEND_DECLARE_FUNCTION_OR_CLASS 100
#define ZEND_EXT_STMT 101
#define ZEND_EXT_FCALL_BEGIN 102
#define ZEND_EXT_FCALL_END 103
#define ZEND_EXT_NOP 104
#define ZEND_TICKS 105
/* end of block */
/* global/local fetches */
#define ZEND_FETCH_GLOBAL 0
#define ZEND_FETCH_LOCAL 1
#define ZEND_FETCH_STATIC 2
/* var status for backpatching */
#define BP_VAR_R 0
#define BP_VAR_W 1
#define BP_VAR_RW 2
#define BP_VAR_IS 3
#define BP_VAR_NA 4 /* if not applicable */
#define BP_VAR_FUNC_ARG 5
#define BP_VAR_UNSET 6
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_OVERLOADED_FUNCTION 3
#define ZEND_EVAL_CODE 4
#define ZEND_INTERNAL_CLASS 1
#define ZEND_USER_CLASS 2
#define ZEND_EVAL (1<<0)
#define ZEND_INCLUDE (1<<1)
#define ZEND_INCLUDE_ONCE (1<<2)
#define ZEND_REQUIRE (1<<3)
#define ZEND_REQUIRE_ONCE (1<<4)
#define ZEND_ISSET (1<<0)
#define ZEND_ISEMPTY (1<<1)
#define ZEND_CT (1<<0)
#define ZEND_RT (1<<1)
#define ZEND_HANDLE_FILENAME 0
#define ZEND_HANDLE_FD 1
#define ZEND_HANDLE_FP 2
#define ZEND_HANDLE_STDIOSTREAM 3
#define ZEND_HANDLE_FSTREAM 4
#define ZEND_DECLARE_CLASS 1
#define ZEND_DECLARE_FUNCTION 2
#define ZEND_DECLARE_INHERITED_CLASS 3
#define ZEND_FETCH_STANDARD 0
#define ZEND_FETCH_ADD_LOCK 1
#define ZEND_MEMBER_FUNC_CALL 1<<0
#define ZEND_CTOR_CALL 1<<1
#define AI_USE_PTR(ai) \
if ((ai).ptr_ptr) { \
(ai).ptr = *((ai).ptr_ptr); \
(ai).ptr_ptr = &((ai).ptr); \
} else { \
(ai).ptr = NULL; \
}
/* Lost In Stupid Parentheses */
#define ARG_SHOULD_BE_SENT_BY_REF(offset, conduct_check, arg_types) \
( \
conduct_check \
&& arg_types \
&& \
( \
( \
offset<=arg_types[0] \
&& arg_types[offset]==BYREF_FORCE \
) \
|| ( \
offset>=arg_types[0] \
&& arg_types[arg_types[0]]==BYREF_FORCE_REST \
) \
) \
)
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
END_EXTERN_C()
#endif /* ZEND_COMPILE_H */
+86
View File
@@ -0,0 +1,86 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_CONFIG_W32_H
#define ZEND_CONFIG_W32_H
#include <string.h>
#include <windows.h>
#include <float.h>
typedef unsigned long ulong;
typedef unsigned int uint;
#define HAVE_ALLOCA 1
#define HAVE_LIMITS_H 1
#include <malloc.h>
#undef HAVE_KILL
#define HAVE_GETPID 1
/* #define HAVE_ALLOCA_H 1 */
#define HAVE_MEMCPY 1
#define HAVE_STRDUP 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDIOSTR_H 1
#define HAVE_CLASS_ISTDIOSTREAM
#define istdiostream stdiostream
#define HAVE_STDARG_H 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
#define vsnprintf _vsnprintf
#define zend_isinf(a) 0
#define zend_sprintf sprintf
/* This will cause the compilation process to be MUCH longer, but will generate
* a much quicker PHP binary
*/
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif
#define zend_finite(A) _finite(A)
#define zend_isnan(A) _isnan(A)
#ifdef LIBZEND_EXPORTS
# define ZEND_API __declspec(dllexport)
#else
# define ZEND_API __declspec(dllimport)
#endif
#define ZEND_DLEXPORT __declspec(dllexport)
/* 0x00200000L is MB_SERVICE_NOTIFICATION, which is only supported under Windows NT
* (and requires _WIN32_WINNT to be defined, which prevents the resulting executable
* from running under Windows 9x
* Windows 9x should silently ignore it, so it's being used here directly
*/
#ifndef MB_SERVICE_NOTIFICATION
#define MB_SERVICE_NOTIFICATION 0x00200000L
#endif
#define ZEND_SERVICE_MB_STYLE (MB_TOPMOST|MB_SERVICE_NOTIFICATION)
#endif /* ZEND_CONFIG_W32_H */
+267
View File
@@ -0,0 +1,267 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_constants.h"
#include "zend_variables.h"
#include "zend_operators.h"
#include "zend_globals.h"
void free_zend_constant(zend_constant *c)
{
if (!(c->flags & CONST_PERSISTENT)) {
zval_dtor(&c->value);
}
free(c->name);
}
void copy_zend_constant(zend_constant *c)
{
c->name = zend_strndup(c->name, c->name_len);
if (!(c->flags & CONST_PERSISTENT)) {
zval_copy_ctor(&c->value);
}
}
void zend_copy_constants(HashTable *target, HashTable *source)
{
zend_constant tmp_constant;
zend_hash_copy(target, source, (copy_ctor_func_t) copy_zend_constant, &tmp_constant, sizeof(zend_constant));
}
static int clean_non_persistent_constant(zend_constant *c)
{
if (c->flags & CONST_PERSISTENT) {
return 0;
} else {
return 1;
}
}
static int clean_module_constant(zend_constant *c, int *module_number)
{
if (c->module_number == *module_number) {
return 1;
} else {
return 0;
}
}
void clean_module_constants(int module_number)
{
ELS_FETCH();
zend_hash_apply_with_argument(EG(zend_constants), (int (*)(void *,void *)) clean_module_constant, (void *) &module_number);
}
int zend_startup_constants(ELS_D)
{
#ifdef ZEND_WIN32
DWORD dwBuild=0;
DWORD dwVersion = GetVersion();
DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
#endif
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
return FAILURE;
}
return SUCCESS;
}
void zend_register_standard_constants(ELS_D)
{
REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_CORE_ERROR", E_CORE_ERROR, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_CORE_WARNING", E_CORE_WARNING, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_ERROR", E_COMPILE_ERROR, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_WARNING", E_COMPILE_WARNING, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
/* true/false constants */
{
zend_constant c;
c.value.type = IS_BOOL;
c.flags = CONST_PERSISTENT;
c.module_number = 0;
c.name = zend_strndup(ZEND_STRL("TRUE"));
c.name_len = sizeof("TRUE");
c.value.value.lval = 1;
c.value.type = IS_BOOL;
zend_register_constant(&c ELS_CC);
c.name = zend_strndup(ZEND_STRL("FALSE"));
c.name_len = sizeof("FALSE");
c.value.value.lval = 0;
c.value.type = IS_BOOL;
zend_register_constant(&c ELS_CC);
c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE"));
c.name_len = sizeof("ZEND_THREAD_SAFE");
c.value.value.lval = ZTS_V;
c.value.type = IS_BOOL;
zend_register_constant(&c ELS_CC);
c.name = zend_strndup(ZEND_STRL("NULL"));
c.name_len = sizeof("NULL");
c.value.type = IS_NULL;
zend_register_constant(&c ELS_CC);
}
}
int zend_shutdown_constants(ELS_D)
{
zend_hash_destroy(EG(zend_constants));
free(EG(zend_constants));
return SUCCESS;
}
void clean_non_persistent_constants(void)
{
ELS_FETCH();
zend_hash_apply(EG(zend_constants), (int (*)(void *)) clean_non_persistent_constant);
}
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number ELS_DC)
{
zend_constant c;
c.value.type = IS_LONG;
c.value.value.lval = lval;
c.flags = flags;
c.name = zend_strndup(name,name_len);
c.name_len = name_len;
c.module_number = module_number;
zend_register_constant(&c ELS_CC);
}
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number ELS_DC)
{
zend_constant c;
c.value.type = IS_DOUBLE;
c.value.value.dval = dval;
c.flags = flags;
c.name = zend_strndup(name,name_len);
c.name_len = name_len;
c.module_number = module_number;
zend_register_constant(&c ELS_CC);
}
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number ELS_DC)
{
zend_constant c;
c.value.type = IS_STRING;
c.value.value.str.val = strval;
c.value.value.str.len = strlen;
c.flags = flags;
c.name = zend_strndup(name,name_len);
c.name_len = name_len;
c.module_number = module_number;
zend_register_constant(&c ELS_CC);
}
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number ELS_DC)
{
zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number ELS_CC);
}
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result)
{
zend_constant *c;
char *lookup_name = estrndup(name,name_len);
int retval;
ELS_FETCH();
zend_str_tolower(lookup_name, name_len);
if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
if ((c->flags & CONST_CS) && memcmp(c->name, name, name_len)!=0) {
retval=0;
} else {
retval=1;
*result = c->value;
zval_copy_ctor(result);
}
} else {
retval=0;
}
efree(lookup_name);
return retval;
}
ZEND_API int zend_register_constant(zend_constant *c ELS_DC)
{
char *lowercase_name = zend_strndup(c->name, c->name_len);
int ret = SUCCESS;
#if 0
printf("Registering constant for module %d\n",c->module_number);
#endif
zend_str_tolower(lowercase_name, c->name_len);
if (zend_hash_add(EG(zend_constants), lowercase_name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
zval_dtor(&c->value);
zend_error(E_NOTICE,"Constant %s already defined",lowercase_name);
ret = FAILURE;
}
free(lowercase_name);
return ret;
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+64
View File
@@ -0,0 +1,64 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_CONSTANTS_H
#define ZEND_CONSTANTS_H
#include "zend_globals.h"
#define CONST_CS 0x1 /* Case Sensitive */
#define CONST_PERSISTENT 0x2
typedef struct _zend_constant {
zval value;
int flags;
char *name;
uint name_len;
int module_number;
} zend_constant;
#define REGISTER_LONG_CONSTANT(name,lval,flags) zend_register_long_constant((name),sizeof(name),(lval),(flags),module_number ELS_CC)
#define REGISTER_DOUBLE_CONSTANT(name,dval,flags) zend_register_double_constant((name),sizeof(name),(dval),(flags),module_number ELS_CC)
#define REGISTER_STRING_CONSTANT(name,str,flags) zend_register_string_constant((name),sizeof(name),(str),(flags),module_number ELS_CC)
#define REGISTER_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),module_number ELS_CC)
#define REGISTER_MAIN_LONG_CONSTANT(name,lval,flags) zend_register_long_constant((name),sizeof(name),(lval),(flags),0 ELS_CC)
#define REGISTER_MAIN_DOUBLE_CONSTANT(name,dval,flags) zend_register_double_constant((name),sizeof(name),(dval),(flags),0 ELS_CC)
#define REGISTER_MAIN_STRING_CONSTANT(name,str,flags) zend_register_string_constant((name),sizeof(name),(str),(flags),0 ELS_CC)
#define REGISTER_MAIN_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),0 ELS_CC)
void clean_module_constants(int module_number);
void free_zend_constant(zend_constant *c);
int zend_startup_constants(ELS_D);
int zend_shutdown_constants(ELS_D);
void zend_register_standard_constants(ELS_D);
void clean_non_persistent_constants(void);
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result);
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number ELS_DC);
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number ELS_DC);
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number ELS_DC);
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number ELS_DC);
ZEND_API int zend_register_constant(zend_constant *c ELS_DC);
void zend_copy_constants(HashTable *target, HashTable *sourc);
void copy_zend_constant(zend_constant *c);
#define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant
#endif
+62
View File
@@ -0,0 +1,62 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
typedef struct _dynamic_array {
char *array;
unsigned int element_size;
unsigned int current;
unsigned int allocated;
} dynamic_array;
ZEND_API int zend_dynamic_array_init(dynamic_array *da, unsigned int element_size, unsigned int size)
{
da->element_size = element_size;
da->allocated = size;
da->current = 0;
da->array = (char *) emalloc(size*element_size);
if (da->array == NULL) {
return 1;
}
return 0;
}
ZEND_API void *zend_dynamic_array_push(dynamic_array *da)
{
if (da->current == da->allocated) {
da->allocated *= 2;
da->array = (char *) erealloc(da->array, da->allocated*da->element_size);
}
return (void *)(da->array+(da->current++)*da->element_size);
}
ZEND_API void *zend_dynamic_array_pop(dynamic_array *da)
{
return (void *)(da->array+(--(da->current))*da->element_size);
}
ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index)
{
if (index >= da->current) {
return NULL;
}
return (void *)(da->array+index*da->element_size);
}
+38
View File
@@ -0,0 +1,38 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_DYNAMIC_ARRAY_H
#define ZEND_DYNAMIC_ARRAY_H
typedef struct _dynamic_array {
char *array;
unsigned int element_size;
unsigned int last_used;
unsigned int allocated;
} dynamic_array;
BEGIN_EXTERN_C()
ZEND_API int zend_dynamic_array_init(dynamic_array *da);
ZEND_API void *zend_dynamic_array_push(dynamic_array *da);
ZEND_API void *zend_dynamic_array_pop(dynamic_array *da);
ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index);
END_EXTERN_C()
#endif /* ZEND_DYNAMIC_ARRAY_H */
+40
View File
@@ -0,0 +1,40 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_ERRORS_H
#define ZEND_ERRORS_H
#define E_ERROR (1<<0L)
#define E_WARNING (1<<1L)
#define E_PARSE (1<<2L)
#define E_NOTICE (1<<3L)
#define E_CORE_ERROR (1<<4L)
#define E_CORE_WARNING (1<<5L)
#define E_COMPILE_ERROR (1<<6L)
#define E_COMPILE_WARNING (1<<7L)
#define E_USER_ERROR (1<<8L)
#define E_USER_WARNING (1<<9L)
#define E_USER_NOTICE (1<<10L)
#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
#endif /* ZEND_ERRORS_H */
+2336
View File
File diff suppressed because it is too large. Load diff
+213
View File
@@ -0,0 +1,213 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_EXECUTE_H
#define ZEND_EXECUTE_H
#include "zend_compile.h"
#include "zend_hash.h"
#include "zend_variables.h"
#include "zend_execute_locks.h"
typedef union _temp_variable {
zval tmp_var;
struct {
zval **ptr_ptr;
zval *ptr;
} var;
struct {
zval tmp_var; /* a dummy */
union {
struct {
zval *str;
int offset;
} str_offset;
zend_property_reference overloaded_element;
} data;
unsigned char type;
} EA;
} temp_variable;
ZEND_API extern void (*zend_execute)(zend_op_array *op_array ELS_DC);
void init_executor(CLS_D ELS_DC);
void shutdown_executor(ELS_D);
void execute(zend_op_array *op_array ELS_DC);
ZEND_API int zend_is_true(zval *op);
static inline void safe_free_zval_ptr(zval *p)
{
ELS_FETCH();
if (p!=EG(uninitialized_zval_ptr)) {
FREE_ZVAL(p);
}
}
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name CLS_DC ELS_DC);
static inline int i_zend_is_true(zval *op)
{
int result;
switch (op->type) {
case IS_NULL:
result = 0;
break;
case IS_LONG:
case IS_BOOL:
case IS_RESOURCE:
result = (op->value.lval?1:0);
break;
case IS_DOUBLE:
result = (op->value.dval ? 1 : 0);
break;
case IS_STRING:
if (op->value.str.len == 0
|| (op->value.str.len==1 && op->value.str.val[0]=='0')) {
result = 0;
} else {
result = 1;
}
break;
case IS_ARRAY:
result = (zend_hash_num_elements(op->value.ht)?1:0);
break;
case IS_OBJECT:
result = (zend_hash_num_elements(op->value.obj.properties)?1:0);
break;
default:
result = 0;
break;
}
return result;
}
ZEND_API int zval_update_constant(zval **pp, void *arg);
/* dedicated Zend executor functions - do not use! */
static inline void zend_ptr_stack_clear_multiple(ELS_D)
{
void **p = EG(argument_stack).top_element-2;
int delete_count = (ulong) *p;
EG(argument_stack).top -= (delete_count+2);
while (--delete_count>=0) {
zval_ptr_dtor((zval **) --p);
}
EG(argument_stack).top_element = p;
}
static inline int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC)
{
void **p = EG(argument_stack).top_element-2;
int arg_count = (ulong) *p;
if (requested_arg>arg_count) {
return FAILURE;
}
*data = (p-arg_count+requested_arg-1);
return SUCCESS;
}
#if SUPPORT_INTERACTIVE
void execute_new_code(CLS_D);
#endif
/* services */
ZEND_API char *get_active_function_name(void);
ZEND_API char *zend_get_executed_filename(ELS_D);
ZEND_API uint zend_get_executed_lineno(ELS_D);
ZEND_API zend_bool zend_is_executing(void);
void zend_set_timeout(long seconds);
void zend_unset_timeout(void);
ZEND_API void zend_timeout(int dummy);
#ifdef ZEND_WIN32
void zend_init_timeout_thread();
void zend_shutdown_timeout_thread();
#define WM_REGISTER_ZEND_TIMEOUT (WM_USER+1)
#define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
#endif
#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
#define zendi_zval_dtor(p) zval_dtor(&(p))
#define active_opline (*EG(opline_ptr))
static inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC)
{
zval *variable_ptr;
zval *value_ptr;
if (!value_ptr_ptr || !variable_ptr_ptr) {
zend_error(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
return;
}
variable_ptr = *variable_ptr_ptr;
value_ptr = *value_ptr_ptr;
if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
/* } else if (variable_ptr==&EG(uninitialized_zval) || variable_ptr!=value_ptr) { */
} else if (variable_ptr_ptr != value_ptr_ptr) {
variable_ptr->refcount--;
if (variable_ptr->refcount==0) {
zendi_zval_dtor(*variable_ptr);
FREE_ZVAL(variable_ptr);
}
if (!PZVAL_IS_REF(value_ptr)) {
/* break it away */
value_ptr->refcount--;
if (value_ptr->refcount>0) {
ALLOC_ZVAL(*value_ptr_ptr);
**value_ptr_ptr = *value_ptr;
value_ptr = *value_ptr_ptr;
zendi_zval_copy_ctor(*value_ptr);
}
value_ptr->refcount = 1;
value_ptr->is_ref = 1;
}
*variable_ptr_ptr = value_ptr;
value_ptr->refcount++;
} else {
if (variable_ptr->refcount>1) { /* we need to break away */
SEPARATE_ZVAL(variable_ptr_ptr);
}
(*variable_ptr_ptr)->is_ref = 1;
}
if (result && !(result->u.EA.type & EXT_TYPE_UNUSED)) {
Ts[result->u.var].var.ptr_ptr = variable_ptr_ptr;
SELECTIVE_PZVAL_LOCK(*variable_ptr_ptr, result);
AI_USE_PTR(Ts[result->u.var].var);
}
}
#define IS_OVERLOADED_OBJECT 1
#define IS_STRING_OFFSET 2
#endif /* ZEND_EXECUTE_H */
+708
View File
@@ -0,0 +1,708 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include <stdio.h>
#include <signal.h>
#include "zend.h"
#include "zend_compile.h"
#include "zend_execute.h"
#include "zend_API.h"
#include "zend_ptr_stack.h"
#include "zend_constants.h"
#include "zend_extensions.h"
#include "zend_execute_locks.h"
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
ZEND_API void (*zend_execute)(zend_op_array *op_array ELS_DC);
#ifdef ZEND_WIN32
#include <process.h>
/* true global */
static WNDCLASS wc;
static HWND timeout_window;
static HANDLE timeout_thread_event;
static DWORD timeout_thread_id;
static int timeout_thread_initialized=0;
#endif
#if ZEND_DEBUG
static void (*original_sigsegv_handler)(int);
static void zend_handle_sigsegv(int dummy)
{
fflush(stdout);
fflush(stderr);
if (original_sigsegv_handler==zend_handle_sigsegv) {
signal(SIGSEGV, original_sigsegv_handler);
} else {
signal(SIGSEGV, SIG_DFL);
}
{
ELS_FETCH();
fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
active_opline->opcode,
active_opline-EG(active_op_array)->opcodes,
get_active_function_name(),
zend_get_executed_filename(ELS_C),
zend_get_executed_lineno(ELS_C));
}
if (original_sigsegv_handler!=zend_handle_sigsegv) {
original_sigsegv_handler(dummy);
}
}
#endif
static void zend_extension_activator(zend_extension *extension)
{
if (extension->activate) {
extension->activate();
}
}
static void zend_extension_deactivator(zend_extension *extension)
{
if (extension->deactivate) {
extension->deactivate();
}
}
static int is_not_internal_function(zend_function *function)
{
return(function->type != ZEND_INTERNAL_FUNCTION);
}
static int is_not_internal_class(zend_class_entry *ce)
{
return(ce->type != ZEND_INTERNAL_CLASS);
}
void init_executor(CLS_D ELS_DC)
{
INIT_ZVAL(EG(uninitialized_zval));
INIT_ZVAL(EG(error_zval));
EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
EG(error_zval_ptr)=&EG(error_zval);
zend_ptr_stack_init(&EG(arg_types_stack));
/* destroys stack frame, therefore makes core dumps worthless */
#if 0&&ZEND_DEBUG
original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
#endif
EG(return_value_ptr_ptr) = &EG(global_return_value_ptr);
EG(global_return_value_ptr) = NULL;
EG(symtable_cache_ptr) = EG(symtable_cache)-1;
EG(symtable_cache_limit)=EG(symtable_cache)+SYMTABLE_CACHE_SIZE-1;
EG(no_extensions)=0;
EG(function_table) = CG(function_table);
EG(class_table) = CG(class_table);
EG(in_execution) = 0;
zend_ptr_stack_init(&EG(argument_stack));
zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
EG(active_symbol_table) = &EG(symbol_table);
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_activator);
EG(opline_ptr) = NULL;
EG(garbage_ptr) = 0;
zend_hash_init(&EG(included_files), 5, NULL, NULL, 0);
EG(ticks_count) = 0;
EG(user_error_handler) = NULL;
zend_ptr_stack_init(&EG(user_error_handlers));
EG(orig_error_reporting) = EG(error_reporting);
#ifdef ZEND_WIN32
EG(timed_out) = 0;
#endif
}
void shutdown_executor(ELS_D)
{
zend_ptr_stack_destroy(&EG(arg_types_stack));
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
zend_hash_destroy(*EG(symtable_cache_ptr));
efree(*EG(symtable_cache_ptr));
EG(symtable_cache_ptr)--;
}
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_deactivator);
zend_hash_destroy(&EG(symbol_table));
while (EG(garbage_ptr)--) {
if (EG(garbage)[EG(garbage_ptr)]->refcount==1) {
zval_ptr_dtor(&EG(garbage)[EG(garbage_ptr)]);
}
}
zend_ptr_stack_destroy(&EG(argument_stack));
/* Destroy all op arrays */
zend_hash_apply(EG(function_table), (int (*)(void *)) is_not_internal_function);
zend_hash_apply(EG(class_table), (int (*)(void *)) is_not_internal_class);
zend_destroy_rsrc_list(ELS_C); /* must be destroyed after the main symbol table and
* op arrays are destroyed.
*/
clean_non_persistent_constants();
#if ZEND_DEBUG
signal(SIGSEGV, original_sigsegv_handler);
#endif
zend_hash_destroy(&EG(included_files));
if (EG(user_error_handler)) {
zval_dtor(EG(user_error_handler));
FREE_ZVAL(EG(user_error_handler));
}
zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
zend_ptr_stack_destroy(&EG(user_error_handlers));
EG(error_reporting) = EG(orig_error_reporting);
}
ZEND_API char *get_active_function_name()
{
ELS_FETCH();
switch(EG(function_state_ptr)->function->type) {
case ZEND_USER_FUNCTION: {
char *function_name = ((zend_op_array *) EG(function_state_ptr)->function)->function_name;
if (function_name) {
return function_name;
} else {
return "main";
}
}
break;
case ZEND_INTERNAL_FUNCTION:
return ((zend_internal_function *) EG(function_state_ptr)->function)->function_name;
break;
default:
return NULL;
}
}
ZEND_API char *zend_get_executed_filename(ELS_D)
{
if (EG(active_op_array)) {
return EG(active_op_array)->filename;
} else {
return "[no active file]";
}
}
ZEND_API uint zend_get_executed_lineno(ELS_D)
{
if (EG(opline_ptr)) {
return active_opline->lineno;
} else {
return 0;
}
}
ZEND_API zend_bool zend_is_executing()
{
ELS_FETCH();
return EG(in_execution);
}
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
{
#if DEBUG_ZEND>=2
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, (*zval_ptr)->refcount, (*zval_ptr)->refcount-1);
#endif
(*zval_ptr)->refcount--;
if ((*zval_ptr)->refcount==0) {
zval_dtor(*zval_ptr);
safe_free_zval_ptr(*zval_ptr);
} else if (((*zval_ptr)->refcount == 1) && ((*zval_ptr)->type != IS_OBJECT)) {
(*zval_ptr)->is_ref = 0;
}
}
ZEND_API int zend_is_true(zval *op)
{
return i_zend_is_true(op);
}
ZEND_API int zval_update_constant(zval **pp, void *arg)
{
zval *p = *pp;
zend_bool inline_change = (zend_bool) (unsigned long) arg;
if (p->type == IS_CONSTANT) {
zval c;
int refcount;
SEPARATE_ZVAL(pp);
p = *pp;
refcount = p->refcount;
if (!zend_get_constant(p->value.str.val, p->value.str.len, &c)) {
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
p->value.str.val,
p->value.str.val);
p->type = IS_STRING;
if (!inline_change) {
zval_copy_ctor(p);
}
} else {
if (inline_change) {
STR_FREE(p->value.str.val);
}
*p = c;
}
INIT_PZVAL(p);
p->refcount = refcount;
} else if (p->type == IS_CONSTANT_ARRAY) {
SEPARATE_ZVAL(pp);
p = *pp;
p->type = IS_ARRAY;
zend_hash_apply_with_argument(p->value.ht, (int (*)(void *,void *)) zval_update_constant, (void *) 1);
}
return 0;
}
int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[])
{
zval ***params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
int i;
int ex_retval;
zval *local_retval_ptr;
for (i=0; i<param_count; i++) {
params_array[i] = &params[i];
}
ex_retval = call_user_function_ex(function_table, object, function_name, &local_retval_ptr, param_count, params_array, 1, NULL);
if (local_retval_ptr) {
COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
} else {
INIT_ZVAL(*retval_ptr);
}
efree(params_array);
return ex_retval;
}
int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table)
{
int i;
zval **original_return_value;
HashTable *calling_symbol_table;
zend_function_state function_state;
zend_function_state *original_function_state_ptr;
zend_op_array *original_op_array;
zend_op **original_opline_ptr;
ELS_FETCH();
*retval_ptr_ptr = NULL;
if (function_name->type==IS_ARRAY) { /* assume array($obj, $name) couple */
zval **tmp_object_ptr, **tmp_real_function_name;
if (zend_hash_index_find(function_name->value.ht, 0, (void **) &tmp_object_ptr)==FAILURE) {
return FAILURE;
}
if (zend_hash_index_find(function_name->value.ht, 1, (void **) &tmp_real_function_name)==FAILURE) {
return FAILURE;
}
function_name = *tmp_real_function_name;
SEPARATE_ZVAL_IF_NOT_REF(tmp_object_ptr);
object = *tmp_object_ptr;
object->is_ref = 1;
}
if (object) {
if (object->type != IS_OBJECT) {
return FAILURE;
}
function_table = &object->value.obj.ce->function_table;
}
if (function_name->type!=IS_STRING) {
return FAILURE;
}
original_function_state_ptr = EG(function_state_ptr);
zend_str_tolower(function_name->value.str.val, function_name->value.str.len);
if (zend_hash_find(function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function_state.function)==FAILURE) {
return FAILURE;
}
for (i=0; i<param_count; i++) {
zval *param;
if (function_state.function->common.arg_types
&& i<function_state.function->common.arg_types[0]
&& function_state.function->common.arg_types[i+1]==BYREF_FORCE
&& !PZVAL_IS_REF(*params[i])) {
if ((*params[i])->refcount>1) {
zval *new_zval;
if (no_separation) {
return FAILURE;
}
ALLOC_ZVAL(new_zval);
*new_zval = **params[i];
zval_copy_ctor(new_zval);
new_zval->refcount = 1;
(*params[i])->refcount--;
*params[i] = new_zval;
}
(*params[i])->refcount++;
(*params[i])->is_ref = 1;
param = *params[i];
} else if (*params[i] != &EG(uninitialized_zval)) {
(*params[i])->refcount++;
param = *params[i];
} else {
ALLOC_ZVAL(param);
*param = **(params[i]);
INIT_PZVAL(param);
}
zend_ptr_stack_push(&EG(argument_stack), param);
}
zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) (long) param_count, NULL);
if (function_state.function->type == ZEND_USER_FUNCTION) {
calling_symbol_table = EG(active_symbol_table);
if (symbol_table) {
EG(active_symbol_table) = symbol_table;
} else {
ALLOC_HASHTABLE(EG(active_symbol_table));
zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
}
if (object) {
zval *dummy, **this_ptr;
ALLOC_ZVAL(dummy);
INIT_ZVAL(*dummy);
zend_hash_update(EG(active_symbol_table), "this", sizeof("this"), &dummy, sizeof(zval *), (void **) &this_ptr);
zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC);
}
original_return_value = EG(return_value_ptr_ptr);
original_op_array = EG(active_op_array);
EG(return_value_ptr_ptr) = retval_ptr_ptr;
EG(active_op_array) = (zend_op_array *) function_state.function;
original_opline_ptr = EG(opline_ptr);
zend_execute(EG(active_op_array) ELS_CC);
if (!symbol_table) {
zend_hash_destroy(EG(active_symbol_table));
FREE_HASHTABLE(EG(active_symbol_table));
}
EG(active_symbol_table) = calling_symbol_table;
EG(active_op_array) = original_op_array;
EG(return_value_ptr_ptr)=original_return_value;
EG(opline_ptr) = original_opline_ptr;
} else {
ALLOC_INIT_ZVAL(*retval_ptr_ptr);
((zend_internal_function *) function_state.function)->handler(param_count, *retval_ptr_ptr, object, 1 ELS_CC);
INIT_PZVAL(*retval_ptr_ptr);
}
zend_ptr_stack_clear_multiple(ELS_C);
EG(function_state_ptr) = original_function_state_ptr;
return SUCCESS;
}
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name CLS_DC ELS_DC)
{
zval pv;
zend_op_array *new_op_array;
zend_op_array *original_active_op_array = EG(active_op_array);
zend_function_state *original_function_state_ptr = EG(function_state_ptr);
int original_handle_op_arrays;
int retval;
if (retval_ptr) {
pv.value.str.len = strlen(str)+sizeof("return ;")-1;
pv.value.str.val = emalloc(pv.value.str.len+1);
strcpy(pv.value.str.val, "return ");
strcat(pv.value.str.val, str);
strcat(pv.value.str.val, " ;");
} else {
pv.value.str.len = strlen(str);
pv.value.str.val = estrndup(str, pv.value.str.len);
}
pv.type = IS_STRING;
/*printf("Evaluating '%s'\n", pv.value.str.val);*/
original_handle_op_arrays = CG(handle_op_arrays);
CG(handle_op_arrays) = 0;
new_op_array = compile_string(&pv, string_name CLS_CC);
CG(handle_op_arrays) = original_handle_op_arrays;
if (new_op_array) {
zval *local_retval_ptr=NULL;
zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
zend_op **original_opline_ptr = EG(opline_ptr);
EG(return_value_ptr_ptr) = &local_retval_ptr;
EG(active_op_array) = new_op_array;
EG(no_extensions)=1;
zend_execute(new_op_array ELS_CC);
if (local_retval_ptr) {
if (retval_ptr) {
COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
} else {
zval_ptr_dtor(&local_retval_ptr);
}
} else {
if (retval_ptr) {
INIT_ZVAL(*retval_ptr);
}
}
EG(no_extensions)=0;
EG(opline_ptr) = original_opline_ptr;
EG(active_op_array) = original_active_op_array;
EG(function_state_ptr) = original_function_state_ptr;
destroy_op_array(new_op_array);
efree(new_op_array);
EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
retval = SUCCESS;
} else {
retval = FAILURE;
}
zval_dtor(&pv);
return retval;
}
#if SUPPORT_INTERACTIVE
void execute_new_code(CLS_D)
{
ELS_FETCH();
if (!EG(interactive)
|| CG(active_op_array)->backpatch_count>0
|| CG(active_op_array)->function_name
|| CG(active_op_array)->type!=ZEND_USER_FUNCTION) {
return;
}
CG(active_op_array)->start_op_number = CG(active_op_array)->last_executed_op_number;
CG(active_op_array)->end_op_number = CG(active_op_array)->last;
EG(active_op_array) = CG(active_op_array);
zend_execute(CG(active_op_array) ELS_CC);
zval_ptr_dtor(EG(return_value_ptr_ptr));
CG(active_op_array)->start_op_number = CG(active_op_array)->last_executed_op_number;
}
#endif
ZEND_API void zend_timeout(int dummy)
{
ELS_FETCH();
/* is there any point in this? we're terminating the request anyway...
PLS_FETCH();
PG(connection_status) |= PHP_CONNECTION_TIMEOUT;
*/
zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded",
EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
}
#ifdef ZEND_WIN32
static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_REGISTER_ZEND_TIMEOUT:
/* wParam is the thread id pointer, lParam is the timeout amount in seconds */
if (lParam==0) {
KillTimer(timeout_window, wParam);
} else {
SetTimer(timeout_window, wParam, lParam*1000, NULL);
}
break;
case WM_UNREGISTER_ZEND_TIMEOUT:
/* wParam is the thread id pointer */
KillTimer(timeout_window, wParam);
break;
case WM_TIMER: {
#ifdef ZTS
zend_executor_globals *executor_globals;
executor_globals = ts_resource_ex(executor_globals_id, &wParam);
if (!executor_globals) {
/* Thread died before receiving its timeout? */
break;
}
#endif
KillTimer(timeout_window, wParam);
EG(timed_out) = 1;
}
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}
static unsigned __stdcall timeout_thread_proc(void *pArgs)
{
MSG message;
wc.style=0;
wc.lpfnWndProc = zend_timeout_WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=NULL;
wc.hIcon=NULL;
wc.hCursor=NULL;
wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
wc.lpszMenuName=NULL;
wc.lpszClassName = "Zend Timeout Window";
if(!RegisterClass(&wc)) {
return -1;
}
timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
SetEvent(timeout_thread_event);
while (GetMessage(&message, NULL, 0, 0)) {
SendMessage(timeout_window, message.message, message.wParam, message.lParam);
if (message.message == WM_QUIT) {
break;
}
}
DestroyWindow(timeout_window);
UnregisterClass(wc.lpszClassName, NULL);
return 0;
}
void zend_init_timeout_thread()
{
timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
_beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id);
WaitForSingleObject(timeout_thread_event, INFINITE);
}
void zend_shutdown_timeout_thread()
{
if (!timeout_thread_initialized) {
return;
}
PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0);
}
#endif
/* This one doesn't exists on QNX */
#ifndef SIGPROF
#define SIGPROF 27
#endif
void zend_set_timeout(long seconds)
{
ELS_FETCH();
EG(timeout_seconds) = seconds;
#ifdef ZEND_WIN32
if (timeout_thread_initialized==0 && InterlockedIncrement(&timeout_thread_initialized)==1) {
/* We start up this process-wide thread here and not in zend_startup(), because if Zend
* is initialized inside a DllMain(), you're not supposed to start threads from it.
*/
zend_init_timeout_thread();
}
PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds);
#else
# ifdef HAVE_SETITIMER
{
struct itimerval t_r; /* timeout requested */
sigset_t sigset;
t_r.it_value.tv_sec = seconds;
t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
setitimer(ITIMER_PROF, &t_r, NULL);
signal(SIGPROF, zend_timeout);
sigemptyset(&sigset);
sigaddset(&sigset, SIGPROF);
sigprocmask(SIG_UNBLOCK,&sigset,NULL);
}
# endif
#endif
}
void zend_unset_timeout(void)
{
ELS_FETCH();
#ifdef ZEND_WIN32
PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0);
#else
# ifdef HAVE_SETITIMER
{
struct itimerval no_timeout;
no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
setitimer(ITIMER_PROF, &no_timeout, NULL);
}
# endif
#endif
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef ZEND_EXECUTE_LOCKS_H
#define ZEND_EXECUTE_LOCKS_H
#define PZVAL_LOCK(z) ((z)->refcount++)
#define PZVAL_UNLOCK(z) { ((z)->refcount--); \
if (!(z)->refcount) { \
(z)->refcount = 1; \
(z)->is_ref = 0; \
if (EG(garbage_ptr) == 4) { \
zval_ptr_dtor(&EG(garbage)[0]); \
zval_ptr_dtor(&EG(garbage)[1]); \
EG(garbage)[0] = EG(garbage)[2]; \
EG(garbage)[1] = EG(garbage)[3]; \
EG(garbage_ptr) -= 2; \
} \
EG(garbage)[EG(garbage_ptr)++] = (z); \
} \
}
#define SELECTIVE_PZVAL_LOCK(pzv, pzn) if (!((pzn)->u.EA.type & EXT_TYPE_UNUSED)) { PZVAL_LOCK(pzv); }
#endif /* ZEND_EXECUTE_LOCKS_H */
+213
View File
@@ -0,0 +1,213 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend_extensions.h"
ZEND_API zend_llist zend_extensions;
static int last_resource_number;
int zend_load_extensions(char **extension_paths)
{
char **p = extension_paths;
if (!p) {
return SUCCESS;
}
while (*p) {
if (zend_load_extension(*p)==FAILURE) {
return FAILURE;
}
p++;
}
return SUCCESS;
}
int zend_load_extension(char *path)
{
#if ZEND_EXTENSIONS_SUPPORT
DL_HANDLE handle;
zend_extension *new_extension;
zend_extension_version_info *extension_version_info;
handle = DL_LOAD(path);
if (!handle) {
#ifndef ZEND_WIN32
fprintf(stderr, "Failed loading %s: %s\n", path, dlerror());
#else
fprintf(stderr, "Failed loading %s\n", path);
#endif
return FAILURE;
}
extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
if (!extension_version_info || !new_extension) {
fprintf(stderr, "%s doesn't appear to be a valid Zend extension\n", path);
return FAILURE;
}
if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
fprintf(stderr, "%s requires Zend Engine API version %d\n"
"The installed Zend Engine API version is %d\n\n",
new_extension->name,
extension_version_info->zend_extension_api_no,
ZEND_EXTENSION_API_NO);
DL_UNLOAD(handle);
return FAILURE;
} else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
/* we may be able to allow for downwards compatability in some harmless cases. */
fprintf(stderr, "%s designed to be used with the Zend Engine API %d is outdated\n"
"It requires a more recent version of the Zend Engine\n"
"The installed Zend Engine API version is %d\n"
"Contact %s at %s for a later version of this module.\n\n",
new_extension->name,
extension_version_info->zend_extension_api_no,
ZEND_EXTENSION_API_NO,
new_extension->author,
new_extension->URL);
DL_UNLOAD(handle);
return FAILURE;
} else if (ZTS_V!=extension_version_info->thread_safe) {
fprintf(stderr, "Cannot load %s - it %s thread safe, whereas Zend %s\n",
new_extension->name,
(extension_version_info->thread_safe?"is":"isn't"),
(ZTS_V?"is":"isn't"));
DL_UNLOAD(handle);
return FAILURE;
} else if (ZEND_DEBUG!=extension_version_info->debug) {
fprintf(stderr, "Cannot load %s - it %s debug information, whereas Zend %s\n",
new_extension->name,
(extension_version_info->debug?"contains":"does not contain"),
(ZEND_DEBUG?"does":"does not"));
DL_UNLOAD(handle);
return FAILURE;
}
return zend_register_extension(new_extension, handle);
#else
fprintf(stderr, "Extensions are not supported on this platform.\n");
return FAILURE;
#endif
}
int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
{
#if ZEND_EXTENSIONS_SUPPORT
zend_extension extension;
extension = *new_extension;
extension.handle = handle;
zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension);
zend_llist_add_element(&zend_extensions, &extension);
zend_append_version_info(&extension);
/*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
#endif
return SUCCESS;
}
static void zend_extension_shutdown(zend_extension *extension)
{
#if ZEND_EXTENSIONS_SUPPORT
if (extension->shutdown) {
extension->shutdown(extension);
}
#endif
}
static void zend_extension_startup(zend_extension *extension)
{
if (extension->startup) {
if (extension->startup(extension)!=SUCCESS) {
DL_UNLOAD(extension->handle);
}
}
}
int zend_startup_extensions_mechanism()
{
/* Startup extensions mechanism */
zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
last_resource_number = 0;
return SUCCESS;
}
int zend_startup_extensions()
{
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_startup);
return SUCCESS;
}
void zend_shutdown_extensions()
{
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_shutdown);
zend_llist_destroy(&zend_extensions);
}
void zend_extension_dtor(zend_extension *extension)
{
#if ZEND_EXTENSIONS_SUPPORT && !ZEND_DEBUG
if (extension->handle) {
DL_UNLOAD(extension->handle);
}
#endif
}
static void zend_extension_message_dispatcher(zend_extension *extension, int num_args, va_list args)
{
int message;
void *arg;
if (!extension->message_handler || num_args!=2) {
return;
}
message = va_arg(args, int);
arg = va_arg(args, void *);
extension->message_handler(message, arg);
}
ZEND_API void zend_extension_dispatch_message(int message, void *arg)
{
zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher, 2, message, arg);
}
ZEND_API int zend_get_resource_handle(zend_extension *extension)
{
if (last_resource_number<ZEND_MAX_RESERVED_RESOURCES) {
extension->resource_number = last_resource_number;
return last_resource_number++;
} else {
return -1;
}
}
+98
View File
@@ -0,0 +1,98 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_EXTENSIONS_H
#define ZEND_EXTENSIONS_H
#include "zend_compile.h"
#define ZEND_EXTENSION_API_NO 20001002
typedef struct _zend_extension_version_info {
int zend_extension_api_no;
char *required_zend_version;
unsigned char thread_safe;
unsigned char debug;
} zend_extension_version_info;
typedef struct _zend_extension zend_extension;
struct _zend_extension {
char *name;
char *version;
char *author;
char *URL;
char *copyright;
int (*startup)(zend_extension *extension);
void (*shutdown)(zend_extension *extension);
void (*activate)();
void (*deactivate)();
void (*message_handler)(int message, void *arg);
void (*op_array_handler)(zend_op_array *op_array);
void (*statement_handler)(zend_op_array *op_array);
void (*fcall_begin_handler)(zend_op_array *op_array);
void (*fcall_end_handler)(zend_op_array *op_array);
void (*op_array_ctor)(zend_op_array *op_array);
void (*op_array_dtor)(zend_op_array *op_array);
void *reserved1;
void *reserved2;
void *reserved3;
void *reserved4;
void *reserved5;
void *reserved6;
void *reserved7;
void *reserved8;
DL_HANDLE handle;
int resource_number;
};
ZEND_API int zend_get_resource_handle(zend_extension *extension);
ZEND_API void zend_extension_dispatch_message(int message, void *arg);
#define ZEND_EXTMSG_NEW_EXTENSION 1
#define ZEND_EXTENSION() \
ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
#define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
ZEND_API extern zend_llist zend_extensions;
void zend_extension_dtor(zend_extension *extension);
ZEND_API int zend_load_extension(char *path);
ZEND_API int zend_load_extensions(char **extension_paths);
ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle);
void zend_append_version_info(zend_extension *extension);
int zend_startup_extensions_mechanism(void);
int zend_startup_extensions(void);
void zend_shutdown_extensions(void);
#endif /* ZEND_EXTENSIONS_H */
+140
View File
@@ -0,0 +1,140 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_FAST_CACHE_H
#define ZEND_FAST_CACHE_H
#ifndef ZEND_ENABLE_FAST_CACHE
# if ZEND_DEBUG
# define ZEND_ENABLE_FAST_CACHE 0
# else
# define ZEND_ENABLE_FAST_CACHE 1
# endif
#endif
typedef struct _zend_fast_cache_list_entry {
struct _zend_fast_cache_list_entry *next;
} zend_fast_cache_list_entry;
#define MAX_FAST_CACHE_TYPES 4
#define ZVAL_CACHE_LIST 0
#define HASHTABLE_CACHE_LIST 1
#if ZEND_ENABLE_FAST_CACHE
#include "zend_globals.h"
#include "zend_globals_macros.h"
#include "zend_alloc.h"
#if ZEND_DEBUG
# define RECORD_ZVAL_CACHE_HIT(fc_type) AG(fast_cache_stats)[fc_type][1]++;
# define RECORD_ZVAL_CACHE_MISS(fc_type) AG(fast_cache_stats)[fc_type][0]++;
#else
# define RECORD_ZVAL_CACHE_HIT(fc_type)
# define RECORD_ZVAL_CACHE_MISS(fc_type)
#endif
#define ZEND_FAST_ALLOC(p, type, fc_type) \
{ \
ALS_FETCH(); \
\
if (((p) = (type *) AG(fast_cache_list_head)[fc_type])) { \
AG(fast_cache_list_head)[fc_type] = ((zend_fast_cache_list_entry *) AG(fast_cache_list_head)[fc_type])->next; \
RECORD_ZVAL_CACHE_HIT(fc_type); \
} else { \
(p) = (type *) emalloc(sizeof(type)); \
RECORD_ZVAL_CACHE_MISS(fc_type); \
} \
}
#define ZEND_FAST_FREE(p, fc_type) \
{ \
ALS_FETCH(); \
\
((zend_fast_cache_list_entry *) (p))->next = AG(fast_cache_list_head)[fc_type]; \
AG(fast_cache_list_head)[fc_type] = (zend_fast_cache_list_entry *) (p); \
}
#define ZEND_FAST_ALLOC_REL(p, type, fc_type) \
ZEND_FAST_ALLOC(p, type, fc_type)
#define ZEND_FAST_FREE_REL(p, fc_type) \
ZEND_FAST_FREE(p, fc_type)
#else /* !ZEND_ENABLE_FAST_CACHE */
#define ZEND_FAST_ALLOC(p, type, fc_type) \
(p) = (type *) emalloc(sizeof(type))
#define ZEND_FAST_FREE(p, fc_type) \
efree(p)
#define ZEND_FAST_ALLOC_REL(p, type, fc_type) \
(p) = (type *) emalloc_rel(sizeof(type))
#define ZEND_FAST_FREE_REL(p, fc_type) \
efree_rel(p)
#endif /* ZEND_ENABLE_FAST_CACHE */
/* fast cache for zval's */
#define ALLOC_ZVAL(z) \
ZEND_FAST_ALLOC(z, zval, ZVAL_CACHE_LIST)
#define FREE_ZVAL(z) \
ZEND_FAST_FREE(z, ZVAL_CACHE_LIST)
#define ALLOC_ZVAL_REL(z) \
ZEND_FAST_ALLOC_REL(z, zval, ZVAL_CACHE_LIST)
#define FREE_ZVAL_REL(z) \
ZEND_FAST_FREE_REL(z, ZVAL_CACHE_LIST)
/* fast cache for HashTables */
#define ALLOC_HASHTABLE(ht) \
ZEND_FAST_ALLOC(ht, HashTable, HASHTABLE_CACHE_LIST)
#define FREE_HASHTABLE(ht) \
ZEND_FAST_FREE(ht, HASHTABLE_CACHE_LIST)
#define ALLOC_HASHTABLE_REL(ht) \
ZEND_FAST_ALLOC_REL(ht, HashTable, HASHTABLE_CACHE_LIST)
#define FREE_HASHTABLE_REL(ht) \
ZEND_FAST_FREE_REL(ht, HASHTABLE_CACHE_LIST)
#endif /* ZEND_FAST_CACHE_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+216
View File
@@ -0,0 +1,216 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_GLOBALS_H
#define ZEND_GLOBALS_H
#include <setjmp.h>
#include "zend_globals_macros.h"
#include "zend_stack.h"
#include "zend_ptr_stack.h"
#include "zend_hash.h"
#include "zend_llist.h"
#include "zend_fast_cache.h"
/* Define ZTS if you want a thread-safe Zend */
/*#undef ZTS*/
#ifdef ZTS
#include "../TSRM/TSRM.h"
#ifdef __cplusplus
class ZendFlexLexer;
#endif
BEGIN_EXTERN_C()
ZEND_API extern int compiler_globals_id;
ZEND_API extern int executor_globals_id;
ZEND_API extern int alloc_globals_id;
END_EXTERN_C()
#endif
#define SYMTABLE_CACHE_SIZE 32
#include "zend_compile.h"
/* excpt.h on Digital Unix 4.0 defines function_table */
#undef function_table
typedef struct _zend_declarables {
zval ticks;
} zend_declarables;
struct _zend_compiler_globals {
zend_stack bp_stack;
zend_stack switch_cond_stack;
zend_stack foreach_copy_stack;
zend_stack object_stack;
zend_stack declare_stack;
zend_class_entry class_entry, *active_class_entry;
/* variables for list() compilation */
zend_llist list_llist;
zend_llist dimension_llist;
zend_stack function_call_stack;
char *compiled_filename;
int zend_lineno;
int comment_start_line;
char *heredoc;
int heredoc_len;
zend_op_array *active_op_array;
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable filenames_table;
zend_bool in_compilation;
zend_bool short_tags;
zend_bool asp_tags;
zend_bool allow_call_time_pass_reference;
zend_declarables declarables;
/* For extensions support */
zend_bool extended_info; /* generate extension information for debugger/profiler */
zend_bool handle_op_arrays; /* run op_arrays through op_array handlers */
zend_bool unclean_shutdown;
zend_llist open_files;
#ifdef ZTS
#ifdef __cplusplus
ZendFlexLexer *ZFL;
#else
void *ZFL;
#endif
#endif
};
struct _zend_executor_globals {
zval **return_value_ptr_ptr;
zval uninitialized_zval;
zval *uninitialized_zval_ptr;
zval error_zval;
zval *error_zval_ptr;
zend_function_state *function_state_ptr;
zend_ptr_stack arg_types_stack;
/* for global return() support */
zval *global_return_value_ptr;
/* symbol table cache */
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
HashTable **symtable_cache_limit;
HashTable **symtable_cache_ptr;
zend_op **opline_ptr;
HashTable *active_symbol_table;
HashTable symbol_table; /* main symbol table */
HashTable included_files; /* files already included */
jmp_buf bailout;
int error_reporting;
int orig_error_reporting;
zend_op_array *active_op_array;
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable *zend_constants; /* constants table */
long precision;
int ticks_count;
zend_bool in_execution;
/* for extended information support */
zend_bool no_extensions;
#ifdef ZEND_WIN32
zend_bool timed_out;
#endif
HashTable regular_list;
HashTable persistent_list;
zend_ptr_stack argument_stack;
int free_op1, free_op2;
int (*unary_op)(zval *result, zval *op1);
int (*binary_op)(zval *result, zval *op1, zval *op2);
zval *garbage[4];
int garbage_ptr;
zval *user_error_handler;
zend_ptr_stack user_error_handlers;
/* timeout support */
int timeout_seconds;
int lambda_count;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
#if SUPPORT_INTERACTIVE
int interactive;
#endif
};
struct _zend_alloc_globals {
zend_mem_header *head; /* standard list */
zend_mem_header *phead; /* persistent list */
void *cache[MAX_CACHED_MEMORY][MAX_CACHED_ENTRIES];
unsigned int cache_count[MAX_CACHED_MEMORY];
void *fast_cache_list_head[MAX_FAST_CACHE_TYPES];
#if ZEND_DEBUG
/* for performance tuning */
int cache_stats[MAX_CACHED_MEMORY][2];
int fast_cache_stats[MAX_FAST_CACHE_TYPES][2];
#endif
#if MEMORY_LIMIT
unsigned int memory_limit;
unsigned int allocated_memory;
unsigned char memory_exhausted;
#endif
};
#endif /* ZEND_GLOBALS_H */
+89
View File
@@ -0,0 +1,89 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_GLOBALS_MACROS_H
#define ZEND_GLOBALS_MACROS_H
typedef struct _zend_compiler_globals zend_compiler_globals;
typedef struct _zend_executor_globals zend_executor_globals;
typedef struct _zend_alloc_globals zend_alloc_globals;
/* Compiler */
#ifdef ZTS
# define CLS_D zend_compiler_globals *compiler_globals
# define CLS_DC , CLS_D
# define CLS_C compiler_globals
# define CLS_CC , CLS_C
# define CG(v) (((zend_compiler_globals *) compiler_globals)->v)
# define CLS_FETCH() zend_compiler_globals *compiler_globals = (zend_compiler_globals *) ts_resource(compiler_globals_id)
BEGIN_EXTERN_C()
int zendparse(void *compiler_globals);
END_EXTERN_C()
#else
# define CLS_D void
# define CLS_DC
# define CLS_C
# define CLS_CC
# define CG(v) (compiler_globals.v)
# define CLS_FETCH()
extern ZEND_API struct _zend_compiler_globals compiler_globals;
int zendparse(void);
#endif
/* Executor */
#ifdef ZTS
# define ELS_D zend_executor_globals *executor_globals
# define ELS_DC , ELS_D
# define ELS_C executor_globals
# define ELS_CC , ELS_C
# define EG(v) (executor_globals->v)
# define ELS_FETCH() zend_executor_globals *executor_globals = (zend_executor_globals *) ts_resource(executor_globals_id)
#else
# define ELS_D void
# define ELS_DC
# define ELS_C
# define ELS_CC
# define EG(v) (executor_globals.v)
# define ELS_FETCH()
extern ZEND_API zend_executor_globals executor_globals;
#endif
/* Memory Manager */
#ifdef ZTS
# define ALS_D zend_alloc_globals *alloc_globals
# define ALS_DC , ALS_D
# define ALS_C alloc_globals
# define ALS_CC , ALS_C
# define AG(v) (((zend_alloc_globals *) alloc_globals)->v)
# define ALS_FETCH() zend_alloc_globals *alloc_globals = (zend_alloc_globals *) ts_resource(alloc_globals_id)
#else
# define ALS_D void
# define ALS_DC
# define ALS_C
# define ALS_CC
# define AG(v) (alloc_globals.v)
# define ALS_FETCH()
extern ZEND_API zend_alloc_globals alloc_globals;
#endif
#endif /* ZEND_GLOBALS_MACROS_H */
+1278
View File
File diff suppressed because it is too large. Load diff
+199
View File
@@ -0,0 +1,199 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_HASH_H
#define ZEND_HASH_H
#include <sys/types.h>
#define HASH_KEY_IS_STRING 1
#define HASH_KEY_IS_LONG 2
#define HASH_KEY_NON_EXISTANT 3
#define HASH_UPDATE (1<<0)
#define HASH_ADD (1<<1)
#define HASH_NEXT_INSERT (1<<2)
#define HASH_DEL_KEY 0
#define HASH_DEL_INDEX 1
typedef int (*compare_func_t)(const void *, const void *);
typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t);
typedef void (*dtor_func_t)(void *pDest);
typedef int (*apply_func_t)(void *pDest);
typedef int (*apply_func_arg_t)(void *pDest, void *argument);
typedef ulong (*hash_func_t)(char *arKey, uint nKeyLength);
typedef void (*copy_ctor_func_t)(void *pElement);
struct _hashtable;
typedef struct bucket {
ulong h; /* Used for numeric indexing */
uint nKeyLength;
void *pData;
void *pDataPtr;
struct bucket *pListNext;
struct bucket *pListLast;
struct bucket *pNext;
struct bucket *pLast;
char arKey[1]; /* Must be last element */
} Bucket;
typedef struct _hashtable {
uint nTableSize;
uint nHashSizeIndex;
uint nNumOfElements;
ulong nNextFreeElement;
hash_func_t pHashFunction;
Bucket *pInternalPointer; /* Used for element traversal */
Bucket *pListHead;
Bucket *pListTail;
Bucket **arBuckets;
dtor_func_t pDestructor;
zend_bool persistent;
unsigned char nApplyCount;
zend_bool bApplyProtection;
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;
typedef Bucket* HashPosition;
BEGIN_EXTERN_C()
/* startup/shutdown */
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, int persistent);
ZEND_API int zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, int persistent, zend_bool bApplyProtection);
ZEND_API void zend_hash_destroy(HashTable *ht);
ZEND_API void zend_hash_clean(HashTable *ht);
/* additions/updates/changes */
ZEND_API int zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest,int flag);
#define zend_hash_update(ht,arKey,nKeyLength,pData,nDataSize,pDest) \
zend_hash_add_or_update(ht,arKey,nKeyLength,pData,nDataSize,pDest,HASH_UPDATE)
#define zend_hash_add(ht,arKey,nKeyLength,pData,nDataSize,pDest) \
zend_hash_add_or_update(ht,arKey,nKeyLength,pData,nDataSize,pDest,HASH_ADD)
ZEND_API int zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest,int flag);
#define zend_hash_quick_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest) \
zend_hash_quick_add_or_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest,HASH_UPDATE)
#define zend_hash_quick_add(ht,arKey,nKeyLength,h,pData,nDataSize,pDest) \
zend_hash_quick_add_or_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest,HASH_ADD)
ZEND_API int zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag);
#define zend_hash_index_update(ht,h,pData,nDataSize,pDest) \
zend_hash_index_update_or_next_insert(ht,h,pData,nDataSize,pDest,HASH_UPDATE)
#define zend_hash_next_index_insert(ht,pData,nDataSize,pDest) \
zend_hash_index_update_or_next_insert(ht,0,pData,nDataSize,pDest,HASH_NEXT_INSERT)
typedef struct _zend_hash_key {
char *arKey;
uint nKeyLength;
ulong h;
} zend_hash_key;
typedef int (*apply_func_args_t)(void *pDest, int num_args, va_list args, zend_hash_key *hash_key);
#define ZEND_STD_HASH_APPLIER \
int (*)(void *element, int num_args, va_list args, zend_hash_key *hash_key)
ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func);
ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *);
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, ZEND_STD_HASH_APPLIER, int, ...);
/* Deletes */
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
#define zend_hash_del(ht,arKey,nKeyLength) \
zend_hash_del_key_or_index(ht,arKey,nKeyLength,0,HASH_DEL_KEY)
#define zend_hash_index_del(ht,h) \
zend_hash_del_key_or_index(ht,NULL,0,h,HASH_DEL_INDEX)
ZEND_API ulong zend_get_hash_value(HashTable *ht, char *arKey, uint nKeyLength);
/* Data retreival */
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_hash_quick_find(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
ZEND_API int zend_hash_index_find(HashTable *ht, ulong h, void **pData);
/* Misc */
ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h);
ZEND_API ulong zend_hash_next_free_element(HashTable *ht);
/* traversing */
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(HashTable *ht, char **str_index, ulong *str_length, ulong *num_index, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
#define zend_hash_move_forward(ht) \
zend_hash_move_forward_ex(ht, NULL)
#define zend_hash_move_backwards(ht) \
zend_hash_move_backwards_ex(ht, NULL)
#define zend_hash_get_current_key(ht, str_index, num_index) \
zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, NULL)
#define zend_hash_get_current_key_type(ht) \
zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData) \
zend_hash_get_current_data_ex(ht, pData, NULL)
#define zend_hash_internal_pointer_reset(ht) \
zend_hash_internal_pointer_reset_ex(ht, NULL)
#define zend_hash_internal_pointer_end(ht) \
zend_hash_internal_pointer_end_ex(ht, NULL)
/* Copying, merging and sorting */
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite);
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, zend_bool (*pReplaceOrig)(void *orig, void *p_new));
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber);
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered);
ZEND_API int zend_hash_minmax(HashTable *ht, int (*compar)(const void *, const void *), int flag, void **pData);
ZEND_API int zend_hash_num_elements(HashTable *ht);
ZEND_API int zend_hash_rehash(HashTable *ht);
ZEND_API ulong hashpjw(char *arKey, uint nKeyLength);
#if ZEND_DEBUG
/* debug */
void zend_hash_display_pListTail(HashTable *ht);
void zend_hash_display(HashTable *ht);
#endif
END_EXTERN_C()
#define ZEND_INIT_SYMTABLE(ht) \
ZEND_INIT_SYMTABLE_EX(ht, 2, 0)
#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \
zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
#endif /* ZEND_HASH_H */
+180
View File
@@ -0,0 +1,180 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend-parser.h"
#include "zend_compile.h"
#include "zend_highlight.h"
#include "zend_ptr_stack.h"
#include "zend_globals.h"
#ifndef ZTS
extern char *zendtext;
extern int zendleng;
#else
#define zendtext ((char *) zend_get_zendtext(CLS_C))
#define zendleng zend_get_zendleng(CLS_C)
#endif
ZEND_API void zend_html_putc(char c)
{
switch (c) {
case '\n':
ZEND_PUTS("<br>");
break;
case '<':
ZEND_PUTS("&lt;");
break;
case '>':
ZEND_PUTS("&gt;");
break;
case '&':
ZEND_PUTS("&amp;");
break;
case ' ':
ZEND_PUTS("&nbsp;");
break;
case '\t':
ZEND_PUTS("&nbsp;&nbsp;&nbsp;&nbsp;");
break;
default:
ZEND_PUTC(c);
break;
}
}
ZEND_API void zend_html_puts(char *s, uint len)
{
register char *ptr=s, *end=s+len;
while (ptr<end) {
zend_html_putc(*ptr++);
}
}
ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini)
{
zval token;
int token_type;
char *last_color = syntax_highlighter_ini->highlight_html;
char *next_color;
int in_string=0;
CLS_FETCH();
zend_printf("<code>");
zend_printf("<font color=\"%s\">\n", last_color);
/* highlight stuff coming back from zendlex() */
token.type = 0;
while ((token_type=lex_scan(&token CLS_CC))) {
switch (token_type) {
case T_INLINE_HTML:
next_color = syntax_highlighter_ini->highlight_html;
break;
case T_COMMENT:
next_color = syntax_highlighter_ini->highlight_comment;
break;
case T_OPEN_TAG:
case T_OPEN_TAG_WITH_ECHO:
next_color = syntax_highlighter_ini->highlight_default;
break;
case T_CLOSE_TAG:
next_color = syntax_highlighter_ini->highlight_default;
break;
case T_CONSTANT_ENCAPSED_STRING:
next_color = syntax_highlighter_ini->highlight_string;
break;
case '"':
next_color = syntax_highlighter_ini->highlight_string;
in_string = !in_string;
break;
case T_WHITESPACE:
zend_html_puts(zendtext, zendleng); /* no color needed */
token.type = 0;
continue;
break;
default:
if (token.type==0) {
next_color = syntax_highlighter_ini->highlight_keyword;
} else {
if (in_string) {
next_color = syntax_highlighter_ini->highlight_string;
} else {
next_color = syntax_highlighter_ini->highlight_default;
}
}
break;
}
if (last_color != next_color) {
if (last_color != syntax_highlighter_ini->highlight_html) {
zend_printf("</font>");
}
last_color = next_color;
if (last_color != syntax_highlighter_ini->highlight_html) {
zend_printf("<font color=\"%s\">", last_color);
}
}
switch (token_type) {
case T_END_HEREDOC:
zend_html_puts(token.value.str.val, token.value.str.len);
break;
default:
zend_html_puts(zendtext, zendleng);
break;
}
if (token.type == IS_STRING) {
switch (token_type) {
case T_OPEN_TAG:
case T_OPEN_TAG_WITH_ECHO:
case T_CLOSE_TAG:
case T_WHITESPACE:
break;
default:
efree(token.value.str.val);
break;
}
} else if (token_type == T_END_HEREDOC) {
zend_bool has_semicolon=(strchr(token.value.str.val, ';')?1:0);
efree(token.value.str.val);
if (has_semicolon) {
/* the following semicolon was unput(), ignore it */
lex_scan(&token CLS_CC);
}
}
token.type = 0;
}
if (last_color != syntax_highlighter_ini->highlight_html) {
zend_printf("</font>\n");
}
zend_printf("</font>\n");
zend_printf("</code>");
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+51
View File
@@ -0,0 +1,51 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_HIGHLIGHT_H
#define ZEND_HIGHLIGHT_H
#define HL_COMMENT_COLOR "#FF8000" /* orange */
#define HL_DEFAULT_COLOR "#0000BB" /* blue */
#define HL_HTML_COLOR "#000000" /* black */
#define HL_STRING_COLOR "#DD0000" /* red */
#define HL_BG_COLOR "#FFFFFF" /* white */
#define HL_KEYWORD_COLOR "#007700" /* green */
typedef struct _zend_syntax_highlighter_ini {
char *highlight_html;
char *highlight_comment;
char *highlight_default;
char *highlight_string;
char *highlight_keyword;
} zend_syntax_highlighter_ini;
BEGIN_EXTERN_C()
ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini);
int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini);
int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name);
ZEND_API void zend_html_putc(char c);
ZEND_API void zend_html_puts(char *s, uint len);
END_EXTERN_C()
extern zend_syntax_highlighter_ini syntax_highlighter_ini;
#endif
+152
View File
@@ -0,0 +1,152 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
/* This indenter doesn't really work, it's here for no particular reason. */
#include "zend.h"
#include "zend-parser.h"
#include "zend_compile.h"
#include "zend_indent.h"
#ifndef ZTS
extern char *zendtext;
extern int zendleng;
#else
#define zendtext ((char *) zend_get_zendtext(CLS_C))
#define zendleng zend_get_zendleng(CLS_C)
#endif
static void handle_whitespace(int *emit_whitespace)
{
unsigned char c;
int i;
for (c=0; c<128; c++) {
if (emit_whitespace[c]>0) {
for (i=0; i<emit_whitespace[c]; i++) {
zend_write((char *) &c, 1);
}
}
}
memset(emit_whitespace, 0, sizeof(int)*256);
}
ZEND_API void zend_indent()
{
zval token;
int token_type;
int in_string=0;
int nest_level=0;
int emit_whitespace[256];
int i;
CLS_FETCH();
memset(emit_whitespace, 0, sizeof(int)*256);
/* highlight stuff coming back from zendlex() */
token.type = 0;
while ((token_type=lex_scan(&token CLS_CC))) {
switch (token_type) {
case T_INLINE_HTML:
zend_write(zendtext, zendleng);
break;
case T_WHITESPACE: {
token.type = 0;
/* eat whitespace, emit newlines */
for (i=0; i<zendleng; i++) {
emit_whitespace[(unsigned char) zendtext[i]]++;
}
continue;
}
break;
case '"':
in_string = !in_string;
/* break missing intentionally */
default:
if (token.type==0) {
/* keyword */
switch(token_type) {
case ',':
ZEND_PUTS(", ");
goto dflt_printout;
break;
case '{':
nest_level++;
if (emit_whitespace['\n']>0) {
ZEND_PUTS(" {\n");
memset(emit_whitespace, 0, sizeof(int)*256);
} else {
ZEND_PUTS("{");
}
break;
case '}':
nest_level--;
if (emit_whitespace['\n']==0) {
ZEND_PUTS("\n");
}
for (i=0; i<nest_level; i++) {
ZEND_PUTS(" ");
}
goto dflt_printout;
break;
dflt_printout:
default:
if (emit_whitespace['\n']>0) {
for (i=0; i<emit_whitespace['\n']; i++) {
ZEND_PUTS("\n");
}
memset(emit_whitespace, 0, sizeof(int)*256);
for (i=0; i<nest_level; i++) {
ZEND_PUTS(" ");
}
} else {
handle_whitespace(emit_whitespace);
}
zend_write(zendtext, zendleng);
break;
}
} else {
handle_whitespace(emit_whitespace);
if (in_string) {
zend_write(zendtext, zendleng);
/* a part of a string */
} else {
zend_write(zendtext, zendleng);
}
}
break;
}
if (token.type == IS_STRING) {
switch (token_type) {
case T_OPEN_TAG:
case T_CLOSE_TAG:
case T_WHITESPACE:
break;
default:
efree(token.value.str.val);
break;
}
}
token.type = 0;
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_INDENT_H
#define ZEND_INDENT_H
ZEND_API void zend_indent(void);
#endif /* ZEND_INDENT_H */
+414
View File
@@ -0,0 +1,414 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
/* resource lists */
#include "zend.h"
#include "zend_list.h"
#include "zend_API.h"
#include "zend_globals.h"
ZEND_API int le_index_ptr;
/* true global */
static HashTable list_destructors;
static inline int zend_list_do_insert(HashTable *list, void *ptr, int type, zend_bool valid)
{
int index;
zend_rsrc_list_entry le;
index = zend_hash_next_free_element(list);
if (index==0) index++;
le.ptr=ptr;
le.type=type;
le.refcount=1;
le.valid = valid;
zend_hash_index_update(list, index, (void *) &le, sizeof(zend_rsrc_list_entry), NULL);
return index;
}
static inline int zend_list_do_delete(HashTable *list,int id)
{
zend_rsrc_list_entry *le;
ELS_FETCH();
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
/* printf("del(%d): %d->%d\n", id, le->refcount, le->refcount-1); */
if (--le->refcount<=0) {
return zend_hash_index_del(&EG(regular_list), id);
} else {
return SUCCESS;
}
} else {
return FAILURE;
}
}
static inline void *zend_list_do_find(HashTable *list,int id, int *type)
{
zend_rsrc_list_entry *le;
if (zend_hash_index_find(list, id, (void **) &le)==SUCCESS) {
*type = le->type;
return le->ptr;
} else {
*type = -1;
return NULL;
}
}
ZEND_API int zend_list_insert(void *ptr, int type)
{
ELS_FETCH();
return zend_list_do_insert(&EG(regular_list), ptr, type, 1);
}
ZEND_API int zend_plist_insert(void *ptr, int type)
{
ELS_FETCH();
return zend_list_do_insert(&EG(persistent_list), ptr, type, 1);
}
ZEND_API int zend_list_addref(int id)
{
zend_rsrc_list_entry *le;
ELS_FETCH();
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
/* printf("add(%d): %d->%d\n", id, le->refcount, le->refcount+1); */
le->refcount++;
return SUCCESS;
} else {
return FAILURE;
}
}
ZEND_API int zend_list_delete(int id)
{
ELS_FETCH();
return zend_list_do_delete(&EG(regular_list), id);
}
ZEND_API int zend_plist_delete(int id)
{
ELS_FETCH();
return zend_list_do_delete(&EG(persistent_list), id);
}
ZEND_API int zend_list_convert_to_number(int id)
{
zend_rsrc_list_entry *le;
ELS_FETCH();
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS
&& le->valid) {
return id;
}
return 0;
}
ZEND_API void *zend_list_find(int id, int *type)
{
ELS_FETCH();
return zend_list_do_find(&EG(regular_list), id, type);
}
ZEND_API void *zend_plist_find(int id, int *type)
{
ELS_FETCH();
return zend_list_do_find(&EG(persistent_list), id, type);
}
ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type)
{
int rsrc_id;
rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type);
if (rsrc_result) {
rsrc_result->value.lval = rsrc_id;
rsrc_result->type = IS_RESOURCE;
}
return rsrc_id;
}
ZEND_API int zend_register_false_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type)
{
int rsrc_id;
ELS_FETCH();
rsrc_id = zend_list_do_insert(&EG(regular_list), rsrc_pointer, rsrc_type, 0);
if (rsrc_result) {
rsrc_result->value.lval = rsrc_id;
rsrc_result->type = IS_RESOURCE;
}
return rsrc_id;
}
ZEND_API void *zend_fetch_resource(zval **passed_id, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...)
{
int id;
int actual_resource_type;
void *resource;
va_list resource_types;
int i;
if (default_id==-1) { /* use id */
if (!passed_id) {
if (resource_type_name) {
zend_error(E_WARNING, "No %s resource supplied", resource_type_name);
}
return NULL;
} else if ((*passed_id)->type != IS_RESOURCE) {
if (resource_type_name) {
zend_error(E_WARNING, "Supplied argument is not a valid %s resource", resource_type_name);
}
return NULL;
}
id = (*passed_id)->value.lval;
} else {
id = default_id;
}
resource = zend_list_find(id, &actual_resource_type);
if (!resource) {
if (resource_type_name) {
zend_error(E_WARNING, "%d is not a valid %s resource", id, resource_type_name);
}
return NULL;
}
va_start(resource_types, num_resource_types);
for (i=0; i<num_resource_types; i++) {
if (actual_resource_type == va_arg(resource_types, int)) {
va_end(resource_types);
if (found_resource_type) {
*found_resource_type = actual_resource_type;
}
return resource;
}
}
va_end(resource_types);
if (resource_type_name) {
zend_error(E_WARNING, "Supplied resource is not a valid %s resource", resource_type_name);
}
return NULL;
}
void list_entry_destructor(void *ptr)
{
zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
zend_rsrc_list_dtors_entry *ld;
if (zend_hash_index_find(&list_destructors, le->type,(void **) &ld)==SUCCESS) {
switch (ld->type) {
case ZEND_RESOURCE_LIST_TYPE_STD:
if (ld->list_dtor) {
(ld->list_dtor)(le->ptr);
}
break;
case ZEND_RESOURCE_LIST_TYPE_EX:
if (ld->list_dtor_ex) {
ld->list_dtor_ex(le);
}
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
} else {
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)",le->type);
}
}
void plist_entry_destructor(void *ptr)
{
zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
zend_rsrc_list_dtors_entry *ld;
if (zend_hash_index_find(&list_destructors, le->type,(void **) &ld)==SUCCESS) {
if (ld->plist_dtor) {
(ld->plist_dtor)(le->ptr);
}
} else {
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)",le->type);
}
}
int zend_init_rsrc_list(ELS_D)
{
return zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0);
}
int zend_init_rsrc_plist(ELS_D)
{
return zend_hash_init_ex(&EG(persistent_list), 0, NULL, plist_entry_destructor, 1, 0);
}
void zend_destroy_rsrc_list(ELS_D)
{
zend_hash_graceful_destroy(&EG(regular_list));
}
void zend_destroy_rsrc_plist(ELS_D)
{
zend_hash_graceful_destroy(&EG(persistent_list));
}
static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id)
{
if (le->type == *resource_id) {
return 1;
} else {
return 0;
}
}
static int zend_clean_module_rsrc_dtors_cb(zend_rsrc_list_dtors_entry *ld, int *module_number)
{
if (ld->module_number == *module_number) {
ELS_FETCH();
zend_hash_apply_with_argument(&EG(regular_list), (int (*)(void *,void *)) clean_module_resource, (void *) &(ld->resource_id));
zend_hash_apply_with_argument(&EG(persistent_list), (int (*)(void *,void *)) clean_module_resource, (void *) &(ld->resource_id));
return 1;
} else {
return 0;
}
}
void zend_clean_module_rsrc_dtors(int module_number)
{
zend_hash_apply_with_argument(&list_destructors, (int (*)(void *,void *)) zend_clean_module_rsrc_dtors_cb, (void *) &module_number);
}
ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number)
{
zend_rsrc_list_dtors_entry lde;
#if 0
printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
#endif
lde.list_dtor=(void (*)(void *)) ld;
lde.plist_dtor=(void (*)(void *)) pld;
lde.list_dtor_ex = lde.plist_dtor_ex = NULL;
lde.module_number = module_number;
lde.resource_id = list_destructors.nNextFreeElement;
lde.type = ZEND_RESOURCE_LIST_TYPE_STD;
lde.type_name = NULL;
if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
return FAILURE;
}
return list_destructors.nNextFreeElement-1;
}
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number)
{
zend_rsrc_list_dtors_entry lde;
#if 0
printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
#endif
lde.list_dtor = NULL;
lde.plist_dtor = NULL;
lde.list_dtor_ex = ld;
lde.plist_dtor_ex = pld;
lde.module_number = module_number;
lde.resource_id = list_destructors.nNextFreeElement;
lde.type = ZEND_RESOURCE_LIST_TYPE_EX;
lde.type_name = type_name;
if (zend_hash_next_index_insert(&list_destructors,(void *) &lde, sizeof(zend_rsrc_list_dtors_entry),NULL)==FAILURE) {
return FAILURE;
}
return list_destructors.nNextFreeElement-1;
}
int zend_init_rsrc_list_dtors()
{
return zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
}
void zend_destroy_rsrc_list_dtors()
{
zend_hash_destroy(&list_destructors);
}
char *zend_rsrc_list_get_rsrc_type(int resource)
{
zend_rsrc_list_dtors_entry *lde;
if (zend_hash_index_find(&list_destructors, resource, (void **) &lde)==SUCCESS) {
return lde->type_name;
} else {
return NULL;
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
+109
View File
@@ -0,0 +1,109 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_LIST_H
#define ZEND_LIST_H
#include "zend_hash.h"
#include "zend_globals.h"
#define ZEND_RESOURCE_LIST_TYPE_STD 1
#define ZEND_RESOURCE_LIST_TYPE_EX 2
typedef struct _zend_rsrc_list_entry {
void *ptr;
int type;
int refcount;
zend_bool valid;
} zend_rsrc_list_entry;
typedef void (*rsrc_dtor_func_t)(zend_rsrc_list_entry *rsrc);
#define ZEND_RSRC_DTOR_FUNC(name) void name(zend_rsrc_list_entry *rsrc)
typedef struct _zend_rsrc_list_dtors_entry {
/* old style destructors */
void (*list_dtor)(void *);
void (*plist_dtor)(void *);
/* new style destructors */
rsrc_dtor_func_t list_dtor_ex;
rsrc_dtor_func_t plist_dtor_ex;
char *type_name;
int module_number;
int resource_id;
unsigned char type;
} zend_rsrc_list_dtors_entry;
#define register_list_destructors(ld, pld) zend_register_list_destructors((void (*)(void *))ld, (void (*)(void *))pld, module_number);
ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number);
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, char *type_name, int module_number);
enum list_entry_type {
LE_DB=1000
};
void list_entry_destructor(void *ptr);
void plist_entry_destructor(void *ptr);
void zend_clean_module_rsrc_dtors(int module_number);
int zend_init_rsrc_list(ELS_D);
int zend_init_rsrc_plist(ELS_D);
void zend_destroy_rsrc_list(ELS_D);
void zend_destroy_rsrc_plist(ELS_D);
int zend_init_rsrc_list_dtors();
void zend_destroy_rsrc_list_dtors();
ZEND_API int zend_list_insert(void *ptr, int type);
ZEND_API int zend_plist_insert(void *ptr, int type);
ZEND_API int zend_list_addref(int id);
ZEND_API int zend_list_delete(int id);
ZEND_API int zend_plist_delete(int id);
ZEND_API int zend_list_convert_to_number(int id);
ZEND_API void *zend_list_find(int id, int *type);
ZEND_API void *zend_plist_find(int id, int *type);
ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type);
ZEND_API void *zend_fetch_resource(zval **passed_id, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...);
ZEND_API char *zend_rsrc_list_get_rsrc_type(int resource);
extern ZEND_API int le_index_ptr; /* list entry type for index pointers */
#define ZEND_VERIFY_RESOURCE(rsrc) \
if (!rsrc) { \
RETURN_NULL(); \
}
#define ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type) \
rsrc = (rsrc_type) zend_fetch_resource(passed_id, default_id, resource_type_name, NULL, 1, resource_type); \
ZEND_VERIFY_RESOURCE(rsrc);
#define ZEND_FETCH_RESOURCE2(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type1,resource_type2) \
rsrc = (rsrc_type) zend_fetch_resource(passed_id, default_id, resource_type_name, NULL, 2, resource_type1, resource_type2); \
ZEND_VERIFY_RESOURCE(rsrc);
#define ZEND_REGISTER_RESOURCE(rsrc_result, rsrc_pointer, rsrc_type) \
zend_register_resource(rsrc_result, rsrc_pointer, rsrc_type);
#endif
+275
View File
@@ -0,0 +1,275 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_llist.h"
ZEND_API void zend_llist_init(zend_llist *l, size_t size, void (*dtor)(void *data), unsigned char persistent)
{
l->head = NULL;
l->tail = NULL;
l->size = size;
l->dtor = dtor;
l->persistent = persistent;
}
ZEND_API void zend_llist_add_element(zend_llist *l, void *element)
{
zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
tmp->prev = l->tail;
tmp->next = NULL;
if (l->tail) {
l->tail->next = tmp;
} else {
l->head = tmp;
}
l->tail = tmp;
memcpy(tmp->data, element, l->size);
}
ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element)
{
zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
tmp->next = l->head;
tmp->prev = NULL;
if (l->head) {
l->head->prev = tmp;
} else {
l->tail = tmp;
}
l->head = tmp;
memcpy(tmp->data, element, l->size);
}
ZEND_API void zend_llist_del_element(zend_llist *l, void *element, int (*compare)(void *element1, void *element2))
{
zend_llist_element *current=l->head;
while (current) {
if (compare(current->data, element)) {
if (current->prev) {
current->prev->next = current->next;
} else {
l->head = current->next;
}
if (current->next) {
current->next->prev = current->prev;
} else {
l->tail = current->prev;
}
if (l->dtor) {
l->dtor(current->data);
pefree(current, l->persistent);
}
break;
}
current = current->next;
}
}
ZEND_API void zend_llist_destroy(zend_llist *l)
{
zend_llist_element *current=l->head, *next;
while (current) {
next = current->next;
if (l->dtor) {
l->dtor(current->data);
}
pefree(current, l->persistent);
current = next;
}
}
ZEND_API void zend_llist_clean(zend_llist *l)
{
zend_llist_destroy(l);
l->head = l->tail = NULL;
}
ZEND_API void zend_llist_remove_tail(zend_llist *l)
{
zend_llist_element *old_tail;
if ((old_tail = l->tail)) {
if (l->tail->prev) {
l->tail->prev->next = NULL;
}
l->tail = l->tail->prev;
pefree(old_tail, l->persistent);
}
}
ZEND_API void zend_llist_copy(zend_llist *dst, zend_llist *src)
{
zend_llist_element *ptr;
zend_llist_init(dst, src->size, src->dtor, src->persistent);
ptr = src->head;
while (ptr) {
zend_llist_add_element(dst, ptr->data);
ptr = ptr->next;
}
}
ZEND_API void zend_llist_apply(zend_llist *l, void (*func)(void *data))
{
zend_llist_element *element;
for (element=l->head; element; element=element->next) {
func(element->data);
}
}
ZEND_API void zend_llist_sort(zend_llist *l, llist_compare_func_t comp_func)
{
int list_size=0, i;
zend_llist_element **elements;
zend_llist_element *element, **ptr;
for (element=l->head; element; element=element->next) {
list_size++;
}
if (list_size == 0) {
return;
}
elements = (zend_llist_element **) emalloc(list_size*sizeof(zend_llist_element *));
ptr = &elements[0];
for (element=l->head; element; element=element->next) {
*ptr++ = element;
}
qsort(elements, list_size, sizeof(zend_llist_element *), (int (*)(const void *, const void *)) comp_func);
l->head = elements[0];
elements[0]->prev = NULL;
for (i=1; i<list_size; i++) {
elements[i]->prev = elements[i-1];
elements[i-1]->next = elements[i];
}
elements[i-1]->next = NULL;
l->tail = elements[i-1];
efree(elements);
}
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, void (*func)(void *data, void *arg), void *arg)
{
zend_llist_element *element;
for (element=l->head; element; element=element->next) {
func(element->data, arg);
}
}
ZEND_API void zend_llist_apply_with_arguments(zend_llist *l, llist_apply_with_args_func_t func, int num_args, ...)
{
zend_llist_element *element;
va_list args;
va_start(args, num_args);
for (element=l->head; element; element=element->next) {
func(element->data, num_args, args);
}
va_end(args);
}
ZEND_API int zend_llist_count(zend_llist *l)
{
zend_llist_element *element;
int element_count=0;
for (element=l->head; element; element=element->next) {
element_count++;
}
return element_count;
}
ZEND_API void *zend_llist_get_first_ex(zend_llist *l, zend_llist_position *pos)
{
zend_llist_position *current = pos ? pos : &l->traverse_ptr;
*current = l->head;
if (*current) {
return (*current)->data;
} else {
return NULL;
}
}
ZEND_API void *zend_llist_get_last_ex(zend_llist *l, zend_llist_position *pos)
{
zend_llist_position *current = pos ? pos : &l->traverse_ptr;
*current = l->tail;
if (*current) {
return (*current)->data;
} else {
return NULL;
}
}
ZEND_API void *zend_llist_get_next_ex(zend_llist *l, zend_llist_position *pos)
{
zend_llist_position *current = pos ? pos : &l->traverse_ptr;
if (*current) {
*current = (*current)->next;
if (*current) {
return (*current)->data;
}
}
return NULL;
}
ZEND_API void *zend_llist_get_prev_ex(zend_llist *l, zend_llist_position *pos)
{
zend_llist_position *current = pos ? pos : &l->traverse_ptr;
if (*current) {
*current = (*current)->prev;
if (*current) {
return (*current)->data;
}
}
return NULL;
}
+76
View File
@@ -0,0 +1,76 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_LLIST_H
#define ZEND_LLIST_H
#include <stdlib.h>
typedef struct _zend_llist_element {
struct _zend_llist_element *next;
struct _zend_llist_element *prev;
char data[1]; /* Needs to always be last in the struct */
} zend_llist_element;
typedef struct _zend_llist {
zend_llist_element *head;
zend_llist_element *tail;
size_t size;
void (*dtor)(void *data);
unsigned char persistent;
zend_llist_element *traverse_ptr;
} zend_llist;
typedef int (*llist_compare_func_t)(const zend_llist_element *, const zend_llist_element *);
typedef void(*llist_apply_with_arg_func_t)(void *data, void *arg);
typedef void(*llist_apply_with_args_func_t)(void *data, int num_args, va_list args);
typedef void (*llist_apply_func_t)(void *);
typedef zend_llist_element* zend_llist_position;
BEGIN_EXTERN_C()
ZEND_API void zend_llist_init(zend_llist *l, size_t size, void (*dtor)(void *data), unsigned char persistent);
ZEND_API void zend_llist_add_element(zend_llist *l, void *element);
ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element);
ZEND_API void zend_llist_del_element(zend_llist *l, void *element, int (*compare)(void *element1, void *element2));
ZEND_API void zend_llist_destroy(zend_llist *l);
ZEND_API void zend_llist_clean(zend_llist *l);
ZEND_API void zend_llist_remove_tail(zend_llist *l);
ZEND_API void zend_llist_copy(zend_llist *dst, zend_llist *src);
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t);
ZEND_API void zend_llist_apply_with_argument(zend_llist *l, llist_apply_with_arg_func_t, void *arg);
ZEND_API void zend_llist_apply_with_arguments(zend_llist *l, llist_apply_with_args_func_t func, int num_args, ...);
ZEND_API int zend_llist_count(zend_llist *l);
ZEND_API void zend_llist_sort(zend_llist *l, llist_compare_func_t comp_func);
/* traversal */
ZEND_API void *zend_llist_get_first_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_last_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_next_ex(zend_llist *l, zend_llist_position *pos);
ZEND_API void *zend_llist_get_prev_ex(zend_llist *l, zend_llist_position *pos);
#define zend_llist_get_first(l) zend_llist_get_first_ex(l, NULL)
#define zend_llist_get_last(l) zend_llist_get_last_ex(l, NULL)
#define zend_llist_get_next(l) zend_llist_get_next_ex(l, NULL)
#define zend_llist_get_prev(l) zend_llist_get_prev_ex(l, NULL)
END_EXTERN_C()
#endif /* ZEND_LLIST_H */
+85
View File
@@ -0,0 +1,85 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef MODULES_H
#define MODULES_H
#define INIT_FUNC_ARGS int type, int module_number ELS_DC
#define INIT_FUNC_ARGS_PASSTHRU type, module_number ELS_CC
#define SHUTDOWN_FUNC_ARGS int type, int module_number
#define SHUTDOWN_FUNC_ARGS_PASSTHRU type, module_number
#define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module
#define GINIT_FUNC_ARGS void
#define GINIT_FUNC_ARGS_PASSTHRU
extern unsigned char first_arg_force_ref[];
extern unsigned char first_arg_allow_ref[];
extern unsigned char second_arg_force_ref[];
extern unsigned char second_arg_allow_ref[];
#include "zend.h"
#define ZEND_MODULE_API_NO 20000809
#ifdef ZTS
#define USING_ZTS 1
#else
#define USING_ZTS 0
#endif
#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_DEBUG, USING_ZTS, ZEND_MODULE_API_NO
#define STANDARD_MODULE_PROPERTIES \
NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
#define MODULE_PERSISTENT 1
#define MODULE_TEMPORARY 2
typedef struct _zend_module_entry zend_module_entry;
struct _zend_module_entry {
char *name;
zend_function_entry *functions;
int (*module_startup_func)(INIT_FUNC_ARGS);
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
int (*request_startup_func)(INIT_FUNC_ARGS);
int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);
void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);
int (*global_startup_func)(void);
int (*global_shutdown_func)(void);
int globals_id;
int module_started;
unsigned char type;
void *handle;
int module_number;
unsigned char zend_debug;
unsigned char zts;
unsigned int zend_api;
};
extern HashTable module_registry;
void module_destructor(zend_module_entry *module);
int module_registry_cleanup(zend_module_entry *module);
int module_registry_request_startup(zend_module_entry *module);
#define ZEND_MODULE_DTOR (void (*)(void *)) module_destructor
#endif
+403
View File
@@ -0,0 +1,403 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include <stdio.h>
#include "zend.h"
#include "zend_alloc.h"
#include "zend_compile.h"
#include "zend_extensions.h"
#include "zend_API.h"
static void zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array)
{
if (extension->op_array_ctor) {
extension->op_array_ctor(op_array);
}
}
static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend_op_array *op_array)
{
if (extension->op_array_dtor) {
extension->op_array_dtor(op_array);
}
}
static void op_array_alloc_ops(zend_op_array *op_array)
{
op_array->opcodes = erealloc(op_array->opcodes, (op_array->size)*sizeof(zend_op));
}
void init_op_array(zend_op_array *op_array, int type, int initial_ops_size CLS_DC)
{
op_array->type = type;
#if SUPPORT_INTERACTIVE
{
ELS_FETCH();
op_array->start_op_number = op_array->end_op_number = op_array->last_executed_op_number = 0;
op_array->backpatch_count = 0;
if (EG(interactive)) {
/* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants
* will become invalid
*/
initial_ops_size = 8192;
}
}
#endif
op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint));
*op_array->refcount = 1;
op_array->size = initial_ops_size;
op_array->last = 0;
op_array->opcodes = NULL;
op_array_alloc_ops(op_array);
op_array->T = 0;
op_array->function_name = NULL;
op_array->filename = zend_get_compiled_filename(CLS_C);
op_array->arg_types = NULL;
op_array->brk_cont_array = NULL;
op_array->last_brk_cont = 0;
op_array->current_brk_cont = -1;
op_array->static_variables = NULL;
op_array->uses_globals = 0;
op_array->return_reference = 0;
op_array->done_pass_two = 0;
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_ctor_handler, op_array);
}
ZEND_API void destroy_zend_function(zend_function *function)
{
switch (function->type) {
case ZEND_USER_FUNCTION:
destroy_op_array((zend_op_array *) function);
break;
case ZEND_INTERNAL_FUNCTION:
/* do nothing */
break;
}
}
ZEND_API void destroy_zend_class(zend_class_entry *ce)
{
if (--(*ce->refcount)>0) {
return;
}
switch (ce->type) {
case ZEND_USER_CLASS:
efree(ce->name);
efree(ce->refcount);
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->default_properties);
break;
case ZEND_INTERNAL_CLASS:
free(ce->name);
free(ce->refcount);
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->default_properties);
break;
}
}
void zend_class_add_ref(zend_class_entry *ce)
{
(*ce->refcount)++;
}
ZEND_API void destroy_op_array(zend_op_array *op_array)
{
zend_op *opline = op_array->opcodes;
zend_op *end = op_array->opcodes+op_array->last;
if (op_array->static_variables) {
zend_hash_destroy(op_array->static_variables);
FREE_HASHTABLE(op_array->static_variables);
}
if (--(*op_array->refcount)>0) {
return;
}
efree(op_array->refcount);
while (opline<end) {
if (opline->op1.op_type==IS_CONST) {
#if DEBUG_ZEND>2
printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op1.u.constant);
#endif
zval_dtor(&opline->op1.u.constant);
}
if (opline->op2.op_type==IS_CONST) {
#if DEBUG_ZEND>2
printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op2.u.constant);
#endif
zval_dtor(&opline->op2.u.constant);
}
opline++;
}
efree(op_array->opcodes);
if (op_array->function_name) {
efree(op_array->function_name);
}
if (op_array->arg_types) {
efree(op_array->arg_types);
}
if (op_array->brk_cont_array) {
efree(op_array->brk_cont_array);
}
if (op_array->done_pass_two) {
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_dtor_handler, op_array);
}
}
void init_op(zend_op *op CLS_DC)
{
memset(&op->result, 0, sizeof(znode));
op->lineno = CG(zend_lineno);
op->result.op_type = IS_UNUSED;
op->extended_value = 0;
memset(&op->op1, 0, sizeof(znode));
memset(&op->op2, 0, sizeof(znode));
}
zend_op *get_next_op(zend_op_array *op_array CLS_DC)
{
zend_uint next_op_num = op_array->last++;
zend_op *next_op;
if (next_op_num >= op_array->size) {
#if SUPPORT_INTERACTIVE
ELS_FETCH();
if (EG(interactive)) {
/* we messed up */
zend_printf("Ran out of opcode space!\n"
"You should probably consider writing this huge script into a file!\n");
zend_bailout();
}
#endif
op_array->size *= 2;
op_array_alloc_ops(op_array);
}
next_op = &(op_array->opcodes[next_op_num]);
init_op(next_op CLS_CC);
return next_op;
}
int get_next_op_number(zend_op_array *op_array)
{
return op_array->last;
}
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array)
{
op_array->last_brk_cont++;
op_array->brk_cont_array = erealloc(op_array->brk_cont_array, sizeof(zend_brk_cont_element)*op_array->last_brk_cont);
return &op_array->brk_cont_array[op_array->last_brk_cont-1];
}
static void zend_update_extended_info(zend_op_array *op_array CLS_DC)
{
zend_op *opline = op_array->opcodes, *end=opline+op_array->last;
while (opline<end) {
if (opline->opcode == ZEND_EXT_STMT) {
if (opline+1<end) {
if ((opline+1)->opcode == ZEND_EXT_STMT) {
opline->opcode = ZEND_NOP;
opline++;
continue;
}
opline->lineno = (opline+1)->lineno;
} else {
opline->opcode = ZEND_NOP;
}
}
opline++;
}
opline = get_next_op(op_array CLS_CC);
opline->opcode = ZEND_EXT_STMT;
opline->op1.op_type = IS_UNUSED;
opline->op2.op_type = IS_UNUSED;
if (op_array->last>0) {
opline->lineno= op_array->opcodes[op_array->last-2].lineno;
}
}
static void zend_extension_op_array_handler(zend_extension *extension, zend_op_array *op_array)
{
if (extension->op_array_handler) {
extension->op_array_handler(op_array);
}
}
int pass_two(zend_op_array *op_array)
{
zend_op *opline=op_array->opcodes, *end=opline+op_array->last;
CLS_FETCH();
if (op_array->type!=ZEND_USER_FUNCTION && op_array->type!=ZEND_EVAL_CODE) {
return 0;
}
if (CG(extended_info)) {
zend_update_extended_info(op_array CLS_CC);
}
if (CG(handle_op_arrays)) {
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_handler, op_array);
}
while (opline<end) {
if (opline->op1.op_type==IS_CONST) {
opline->op1.u.constant.is_ref = 1;
opline->op1.u.constant.refcount = 2; /* Make sure is_ref won't be reset */
}
if (opline->op2.op_type==IS_CONST) {
opline->op2.u.constant.is_ref = 1;
opline->op2.u.constant.refcount = 2;
}
opline++;
}
op_array->done_pass_two = 1;
return 0;
}
int print_class(zend_class_entry *class_entry)
{
printf("Class %s:\n", class_entry->name);
zend_hash_apply(&class_entry->function_table, (int (*)(void *)) pass_two);
printf("End of class %s.\n\n", class_entry->name);
return 0;
}
ZEND_API unary_op_type get_unary_op(int opcode)
{
switch(opcode) {
case ZEND_BW_NOT:
return (unary_op_type) bitwise_not_function;
break;
case ZEND_BOOL_NOT:
return (unary_op_type) boolean_not_function;
break;
default:
return (unary_op_type) NULL;
break;
}
}
ZEND_API void *get_binary_op(int opcode)
{
switch (opcode) {
case ZEND_ADD:
case ZEND_ASSIGN_ADD:
return (void *) add_function;
break;
case ZEND_SUB:
case ZEND_ASSIGN_SUB:
return (void *) sub_function;
break;
case ZEND_MUL:
case ZEND_ASSIGN_MUL:
return (void *) mul_function;
break;
case ZEND_DIV:
case ZEND_ASSIGN_DIV:
return (void *) div_function;
break;
case ZEND_MOD:
case ZEND_ASSIGN_MOD:
return (void *) mod_function;
break;
case ZEND_SL:
case ZEND_ASSIGN_SL:
return (void *) shift_left_function;
break;
case ZEND_SR:
case ZEND_ASSIGN_SR:
return (void *) shift_right_function;
break;
case ZEND_CONCAT:
case ZEND_ASSIGN_CONCAT:
return (void *) concat_function;
break;
case ZEND_IS_IDENTICAL:
return (void *) is_identical_function;
break;
case ZEND_IS_NOT_IDENTICAL:
return (void *) is_not_identical_function;
break;
case ZEND_IS_EQUAL:
return (void *) is_equal_function;
break;
case ZEND_IS_NOT_EQUAL:
return (void *) is_not_equal_function;
break;
case ZEND_IS_SMALLER:
return (void *) is_smaller_function;
break;
case ZEND_IS_SMALLER_OR_EQUAL:
return (void *) is_smaller_or_equal_function;
break;
case ZEND_BW_OR:
case ZEND_ASSIGN_BW_OR:
return (void *) bitwise_or_function;
break;
case ZEND_BW_AND:
case ZEND_ASSIGN_BW_AND:
return (void *) bitwise_and_function;
break;
case ZEND_BW_XOR:
case ZEND_ASSIGN_BW_XOR:
return (void *) bitwise_xor_function;
break;
default:
return (void *) NULL;
break;
}
}
File diff suppressed because it is too large. Load diff
+229
View File
@@ -0,0 +1,229 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#ifndef ZEND_OPERATORS_H
#define ZEND_OPERATORS_H
#include <errno.h>
#include <math.h>
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#if WITH_BCMATH
#include "ext/bcmath/number.h"
#endif
#define MAX_LENGTH_OF_LONG 18
#define MAX_LENGTH_OF_DOUBLE 32
ZEND_API int add_function(zval *result, zval *op1, zval *op2);
ZEND_API int sub_function(zval *result, zval *op1, zval *op2);
ZEND_API int mul_function(zval *result, zval *op1, zval *op2);
ZEND_API int div_function(zval *result, zval *op1, zval *op2);
ZEND_API int mod_function(zval *result, zval *op1, zval *op2);
ZEND_API int boolean_or_function(zval *result, zval *op1, zval *op2);
ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2);
ZEND_API int boolean_and_function(zval *result, zval *op1, zval *op2);
ZEND_API int boolean_not_function(zval *result, zval *op1);
ZEND_API int bitwise_not_function(zval *result, zval *op1);
ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2);
ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2);
ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2);
ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2);
ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2);
ZEND_API int concat_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2);
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
static inline int is_numeric_string(char *str, int length, long *lval, double *dval)
{
long local_lval;
double local_dval;
char *end_ptr;
if (!length) {
return 0;
}
errno=0;
local_lval = strtol(str, &end_ptr, 10);
if (errno!=ERANGE && end_ptr == str+length) { /* integer string */
if (lval) {
*lval = local_lval;
}
return IS_LONG;
}
errno=0;
local_dval = strtod(str, &end_ptr);
if (errno!=ERANGE && end_ptr == str+length) { /* floating point string */
if (! zend_finite(local_dval)) {
/* "inf","nan" and maybe other weird ones */
return 0;
}
if (dval) {
*dval = local_dval;
}
#if WITH_BCMATH
if (length>16) {
register char *ptr=str, *end=str+length;
while(ptr<end) {
switch(*ptr++) {
case 'e':
case 'E':
/* scientific notation, not handled by the BC library */
return IS_DOUBLE;
break;
default:
break;
}
}
return FLAG_IS_BC;
} else {
return IS_DOUBLE;
}
#else
return IS_DOUBLE;
#endif
}
return 0;
}
ZEND_API int increment_function(zval *op1);
ZEND_API int decrement_function(zval *op2);
BEGIN_EXTERN_C()
ZEND_API void convert_scalar_to_number(zval *op);
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
ZEND_API void convert_to_long(zval *op);
ZEND_API void convert_to_double(zval *op);
ZEND_API void convert_to_long_base(zval *op, int base);
ZEND_API void convert_to_null(zval *op);
ZEND_API void convert_to_boolean(zval *op);
ZEND_API void convert_to_array(zval *op);
ZEND_API void convert_to_object(zval *op);
ZEND_API void multi_convert_to_long_ex(int argc, ...);
ZEND_API void multi_convert_to_double_ex(int argc, ...);
ZEND_API void multi_convert_to_string_ex(int argc, ...);
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2);
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2);
#define convert_to_string(op) _convert_to_string((op) ZEND_FILE_LINE_CC)
ZEND_API double zend_string_to_double(const char *number, zend_uint length);
END_EXTERN_C()
ZEND_API int zval_is_true(zval *op);
ZEND_API int compare_function(zval *result, zval *op1, zval *op2);
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2);
ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2);
ZEND_API void zend_str_tolower(char *str, unsigned int length);
ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2);
ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length);
ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2);
ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length);
ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2);
ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2);
ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2);
#define convert_to_ex_master(ppzv, lower_type, upper_type) \
if ((*ppzv)->type!=IS_##upper_type) { \
if (!(*ppzv)->is_ref) { \
SEPARATE_ZVAL(ppzv); \
} \
convert_to_##lower_type(*ppzv); \
}
#define convert_to_writable_ex_master(ppzv, lower_type, upper_type) \
if ((*ppzv)->type!=IS_##upper_type) { \
SEPARATE_ZVAL(ppzv); \
convert_to_##lower_type(*ppzv); \
}
#define convert_to_boolean_ex(ppzv) convert_to_ex_master(ppzv, boolean, BOOL)
#define convert_to_long_ex(ppzv) convert_to_ex_master(ppzv, long, LONG)
#define convert_to_double_ex(ppzv) convert_to_ex_master(ppzv, double, DOUBLE)
#define convert_to_string_ex(ppzv) convert_to_ex_master(ppzv, string, STRING)
#define convert_to_array_ex(ppzv) convert_to_ex_master(ppzv, array, ARRAY)
#define convert_to_object_ex(ppzv) convert_to_ex_master(ppzv, object, OBJECT)
#define convert_to_null_ex(ppzv) convert_to_ex_master(ppzv, null, NULL)
#define convert_to_writable_boolean_ex(ppzv) convert_to_writable_ex_master(ppzv, boolean, BOOL)
#define convert_to_writable_long_ex(ppzv) convert_to_writable_ex_master(ppzv, long, LONG)
#define convert_to_writable_double_ex(ppzv) convert_to_writable_ex_master(ppzv, double, DOUBLE)
#define convert_to_writable_string_ex(ppzv) convert_to_writable_ex_master(ppzv, string, STRING)
#define convert_to_writable_array_ex(ppzv) convert_to_writable_ex_master(ppzv, array, ARRAY)
#define convert_to_writable_object_ex(ppzv) convert_to_writable_ex_master(ppzv, object, OBJECT)
#define convert_to_writable_null_ex(ppzv) convert_to_writable_ex_master(ppzv, null, NULL)
#define convert_scalar_to_number_ex(ppzv) \
if ((*ppzv)->type!=IS_LONG && (*ppzv)->type!=IS_DOUBLE) { \
if (!(*ppzv)->is_ref) { \
SEPARATE_ZVAL(ppzv); \
} \
convert_scalar_to_number(*ppzv); \
}
#define Z_LVAL(zval) (zval).value.lval
#define Z_BVAL(zval) ((zend_bool)(zval).value.lval)
#define Z_DVAL(zval) (zval).value.dval
#define Z_STRVAL(zval) (zval).value.str.val
#define Z_STRLEN(zval) (zval).value.str.len
#define Z_ARRVAL(zval) (zval).value.ht
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
#define Z_BVAL_P(zval_p) Z_BVAL(*zval_p)
#define Z_DVAL_P(zval_p) Z_DVAL(*zval_p)
#define Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p)
#define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p)
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)
#define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp)
#define Z_DVAL_PP(zval_pp) Z_DVAL(**zval_pp)
#define Z_STRVAL_PP(zval_pp) Z_STRVAL(**zval_pp)
#define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp)
#define Z_ARRVAL_PP(zval_pp) Z_ARRVAL(**zval_pp)
#define Z_TYPE(zval) (zval).type
#define Z_TYPE_P(zval_p) Z_TYPE(*zval_p)
#define Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp)
#endif
+125
View File
@@ -0,0 +1,125 @@
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
| Copyright (c) 1998-2000 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 0.92 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.zend.com/license/0_92.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
| Zeev Suraski <zeev@zend.com> |
+----------------------------------------------------------------------+
*/
#include "zend.h"
#include "zend_ptr_stack.h"
#ifdef HAVE_STDARG_H
# include <stdarg.h>
#endif
ZEND_API void zend_ptr_stack_init(zend_ptr_stack *stack)
{
stack->top_element = stack->elements = (void **) emalloc(sizeof(void *)*PTR_STACK_BLOCK_SIZE);
stack->max = PTR_STACK_BLOCK_SIZE;
stack->top = 0;
}
ZEND_API inline void zend_ptr_stack_push(zend_ptr_stack *stack, void *ptr)
{
if (stack->top >= stack->max) { /* we need to allocate more memory */
stack->elements = (void **) erealloc(stack->elements, (sizeof(void *) * (stack->max *= 2 )));
stack->top_element = stack->elements+stack->top;
}
stack->top++;
*(stack->top_element++) = ptr;
}
ZEND_API void zend_ptr_stack_n_push(zend_ptr_stack *stack, int count, ...)
{
va_list ptr;
void *elem;
if (stack->top+count > stack->max) { /* we need to allocate more memory */
stack->max *= 2;
stack->max += count;
stack->elements = (void **) erealloc(stack->elements, (sizeof(void *) * (stack->max)));
stack->top_element = stack->elements+stack->top;
}
va_start(ptr, count);
while (count>0) {
elem = va_arg(ptr, void *);
stack->top++;
*(stack->top_element++) = elem;
count--;
}
va_end(ptr);
}
ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...)
{
va_list ptr;
void **elem;
va_start(ptr, count);
while (count>0) {
elem = va_arg(ptr, void **);
*elem = *(--stack->top_element);
stack->top--;
count--;
}
va_end(ptr);
}
ZEND_API inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
{
stack->top--;
return *(--stack->top_element);
}
ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack)
{
if (stack->elements) {
efree(stack->elements);
}
}
ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *))
{
int i = stack->top;
while (--i >= 0) {
func(stack->elements[i]);
}
}
ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements)
{
zend_ptr_stack_apply(stack, func);
if (free_elements) {
int i = stack->top;
while (--i >= 0) {
efree(stack->elements[i]);
}
}
stack->top = 0;
stack->top_element = stack->elements;
}
ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack)
{
return stack->top;
}
Loaded 100 of 2595 files, more files were not shown because too many files have changed in this diff. Show more