mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-08 17:50:50 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3402e4ee84 |
No files matched your search
@@ -1,359 +0,0 @@
|
||||
set $zts = 0
|
||||
|
||||
define ____executor_globals
|
||||
if $zts
|
||||
set $eg = ((zend_executor_globals) (*((void ***) tsrm_ls))[executor_globals_id-1])
|
||||
else
|
||||
set $eg = executor_globals
|
||||
end
|
||||
end
|
||||
|
||||
document ____executor_globals
|
||||
portable way of accessing executor_globals
|
||||
type "set $zts = 1" if you use --enable-maintainer-zts on your configure line
|
||||
end
|
||||
|
||||
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 = 1
|
||||
____printzv $arg0 0
|
||||
end
|
||||
|
||||
document printzv
|
||||
prints content of zval
|
||||
end
|
||||
|
||||
define ____printzv_contents
|
||||
____executor_globals
|
||||
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 "(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)"
|
||||
if $zvalue.value.obj.handlers->get_properties
|
||||
# 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
|
||||
end
|
||||
if $zvalue.type == 6
|
||||
if $zvalue.value.lval
|
||||
printf "true"
|
||||
else
|
||||
printf "false"
|
||||
end
|
||||
end
|
||||
if $zvalue.type == 7
|
||||
printf "#%d", $zvalue.value.lval
|
||||
end
|
||||
printf "\n"
|
||||
end
|
||||
|
||||
define ____printzv
|
||||
____executor_globals
|
||||
set $zvalue = $arg0
|
||||
|
||||
printf "[0x%08x] ", $zvalue
|
||||
|
||||
if $zvalue == $eg.uninitialized_zval_ptr
|
||||
printf "*uninitialized* "
|
||||
end
|
||||
|
||||
set $zcontents = *(struct _zval_struct *) $zvalue
|
||||
if $arg1
|
||||
____printzv_contents $zcontents $arg1
|
||||
else
|
||||
____printzv_contents $zcontents 0
|
||||
end
|
||||
end
|
||||
|
||||
define ____print_const_table
|
||||
set $ht = $arg0
|
||||
set $p = $ht->pListHead
|
||||
|
||||
while $p != 0
|
||||
set $const = *(zend_constant *) $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_contents $const.value 0
|
||||
set $p = $p->pListNext
|
||||
end
|
||||
end
|
||||
|
||||
define print_const_table
|
||||
set $ind = 1
|
||||
printf "[0x%08x] {\n", $arg0
|
||||
____print_const_table $arg0
|
||||
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
|
||||
____executor_globals
|
||||
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 0
|
||||
end
|
||||
if $znode->op_type == 2
|
||||
printf ": "
|
||||
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
||||
____printzv ((union _temp_variable *)$tvar)->tmp_var 0
|
||||
end
|
||||
if $znode->op_type == 4
|
||||
printf ": "
|
||||
set $tvar = (union _temp_variable *)((char *)$eg.current_execute_data->Ts + $znode->u.var)
|
||||
____printzv *$tvar->var.ptr_ptr 0
|
||||
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 zbacktrace
|
||||
____executor_globals
|
||||
dump_bt $eg.current_execute_data
|
||||
end
|
||||
|
||||
document zbacktrace
|
||||
prints backtrace.
|
||||
This command is almost a short cut for
|
||||
> (gdb) ____executor_globals
|
||||
> (gdb) dump_bt $eg.current_execute_data
|
||||
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
|
||||
+35
-159
@@ -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,120 +45,39 @@ Exceptions:
|
||||
doing so, should return that new length, so it doesn't have to be
|
||||
recalculated with strlen() (e.g. php_addslashes())
|
||||
|
||||
[5] NEVER USE strncat(). If you're absolutely sure you know what you're doing,
|
||||
[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.
|
||||
|
||||
[6] 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.
|
||||
|
||||
[7] 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.
|
||||
|
||||
[8] 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
|
||||
|
||||
[9] 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.
|
||||
|
||||
[6] Method names follow the 'studlyCaps' (also referred to as 'bumpy case'
|
||||
or 'camel caps') naming convention, with care taken to minimize the
|
||||
letter count. The initial letter of the name is lowercase, and each
|
||||
letter that starts a new 'word' is capitalized.
|
||||
|
||||
Good:
|
||||
'connect()'
|
||||
'getData()'
|
||||
'buildSomeWidget()'
|
||||
|
||||
Bad:
|
||||
'get_Data()'
|
||||
'buildsomewidget'
|
||||
'getI()'
|
||||
|
||||
[7] Classes should be given descriptive names. Avoid using abbreviations
|
||||
where possible. Each word in the class name should start with a capital
|
||||
letter, with words underscore delimited. The class name should be prefixed
|
||||
with the name of the 'parent set'.
|
||||
|
||||
Good:
|
||||
'Curl'
|
||||
'Foo_Bar'
|
||||
|
||||
Bad:
|
||||
'foobar'
|
||||
'foo_bar'
|
||||
'FooBar'
|
||||
|
||||
|
||||
Syntax and indentation
|
||||
----------------------
|
||||
@@ -176,38 +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.catb.org/~esr/jargon/html/I/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.
|
||||
|
||||
[5] Preprocessor statements (#if and such) MUST start at column one. To
|
||||
indent preprocessor directives you should put the # at the beginning
|
||||
of a line, followed by any number of whitespace.
|
||||
|
||||
Documentation and Folding Hooks
|
||||
-------------------------------
|
||||
|
||||
@@ -217,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)
|
||||
{
|
||||
...
|
||||
@@ -225,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
|
||||
@@ -238,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,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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+90
-267
@@ -36,56 +36,22 @@ PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache_hooks
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2filter
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2handler
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: caudium
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cgi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cli
|
||||
MAINTENANCE: Marcus Boerger <helly@php.net>, Edin Kadribasic <edink@php.net>
|
||||
STATUS: Working
|
||||
SINCE: 4.3.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: continuity
|
||||
PRIMARY MAINTAINER: Alex Leigh <aleigh@php.net>
|
||||
EXTENSION: fhttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: embed
|
||||
PRIMARY MAINTAINER: Edin Kadribasic <edink@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: isapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: milter
|
||||
EXTENSION: nsapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: nsapi
|
||||
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: phttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
@@ -98,47 +64,39 @@ EXTENSION: roxen
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: thttpd
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Odd fixes
|
||||
EXTENSION: servlet
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tux
|
||||
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
|
||||
COMMENT: DBM abstraction for db2, db3, db4, dbm, ndbm, gdbm, ini
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dbase
|
||||
MAINTENANCE: Orphaned
|
||||
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: fbsql
|
||||
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
|
||||
EXTENSION: filepro
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: hyperwave
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: informix
|
||||
PRIMARY MAINTAINER: Danny Heijl <Danny.Heijl@cevi.be>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -151,8 +109,8 @@ STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: interbase
|
||||
PRIMARY MAINTAINER: Ard Biesheuvel <ard@ard.nu>, Jouni Ahto <jouni.ahto@exdec.fi>
|
||||
MAINTENANCE: Maintained
|
||||
PRIMARY MAINTAINER: Jouni Ahto <jah@mork.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msql
|
||||
@@ -166,48 +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
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysqli
|
||||
PRIMARY MAINTAINER: Georg Richter <georg@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Antony Dovgal <tony2001@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oracle
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
COMMENT: Using the new OCI8 driver is encouraged where possible.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ovrimos
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pgsql
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, 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: sqlite
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>, Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0 (Since 4.3.2 in PECL)
|
||||
COMMENT: Integrates SQLite embeddable SQL database engine.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sybase
|
||||
MAINTENANCE: Unknown
|
||||
@@ -217,121 +140,85 @@ EXTENSION: sybase_ct
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== XML extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dom
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>, Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: simplexml
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: soap
|
||||
PRIMARY MAINTAINER: Dmitry Stogov <dmitry@zend.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: wddx
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xml
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Andreas Karajannis <Karajannis@gmd.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working except for persistent connections
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xmlrpc
|
||||
PRIMARY MAINTAINER: Dan Libby
|
||||
MAINTENANCE: UNKNOWN
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xsl
|
||||
PRIMARY MAINTAINER: Christian Stocker <chregu@php.net>, Rob Richards <rrichards@php.net>
|
||||
EXTENSION: oracle
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 5.0
|
||||
COMMENT: Using the new OCI8 driver is encouraged where possible.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
== Other extensions ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: aspell
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
COMMENT: For aspell .27 and greater, check out the pspell extension
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bcmath
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bz2
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: calendar
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: com_dotnet
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Windows
|
||||
SINCE: 5.0
|
||||
EXTENSION: com
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cpdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ctype
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hholzgra@php.net>
|
||||
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: dio
|
||||
MAINTENANCE: Orphaned
|
||||
STATUS: Working
|
||||
SINCE: 4.0.6
|
||||
EXTENSION: cybercash
|
||||
PRIMARY MAINTAINER: Evan Klinger <evan715@sirius.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: domxml
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dotnet
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: exif
|
||||
PRIMARY MAINTAINER: Marcus Boerger <helly@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fam
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: filepro
|
||||
EXTENSION: ftp
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ftp
|
||||
PRIMARY MAINTAINER: Stefan Esser (sesser@php.net)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gd
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
@@ -341,100 +228,47 @@ EXTENSION: gettext
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gmp
|
||||
EXTENSION: icap
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: hwapi
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: iconv
|
||||
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
STATUS: Obsolete
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: imap
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ircg
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>
|
||||
EXTENSION: java
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mbstring
|
||||
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcal
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
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
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcve
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mhash
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mime_magic
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Deprecated
|
||||
STATUS: Experimental
|
||||
COMMENT: Use PECL's fileinfo extension instead
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ming
|
||||
PRIMARY MAINTAINER: Frank M. Kromann
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mnogosearch
|
||||
PRIMARY MAINTAINER: Sergey Kartashoff <gluke@mail.ru>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mono
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
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: ncurses
|
||||
PRIMARY MAINTAINER Ilia Alshanetsky <iliaa@php.net>, Wez Furlong <wez@php.net>, Hartmut Holzgraefe <hholzgra@php.net>, Georg Richter <georg@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcntl
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcre
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@ispi.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -469,12 +303,6 @@ 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
|
||||
@@ -482,13 +310,14 @@ STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sockets
|
||||
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvmsg
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: swf
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unix (won't change)
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvsem
|
||||
MAINTENANCE: Unknown
|
||||
@@ -498,32 +327,26 @@ EXTENSION: sysvshm
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tidy
|
||||
PRIMARY MAINTAINER: John Coggeshall <john@php.net>, Ilia Alshanetsky <iliaa@php.net>
|
||||
EXTENSION: wddx
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@ispi.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xml
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@digicol.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: tokenizer
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: w32api
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: yaz
|
||||
PRIMARY MAINTAINER: Adam Dickmeiss <adam@indexdata.dk>
|
||||
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
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
# iptc?
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, Version 3.0
|
||||
Copyright (c) 1999 - 2003 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>.
|
||||
@@ -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
|
||||
@@ -1,76 +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)
|
||||
|
||||
libphp5.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 libphp5.la $(phptempdir)/libphp5.la >/dev/null 2>&1
|
||||
|
||||
libs/libphp5.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/libphp5.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)/libphp5.$(SHLIB_SUFFIX_NAME); then \
|
||||
for i in 0.0.0 0.0 0; do \
|
||||
if test -r $(phptempdir)/libphp5.$(SHLIB_SUFFIX_NAME).$$i; then \
|
||||
$(LN_S) $(phptempdir)/libphp5.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp5.$(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 -o -name \*.o | xargs rm -f
|
||||
find . -name \*.la -o -name \*.a | xargs rm -f
|
||||
find . -name \*.so | xargs rm -f
|
||||
find . -name .libs -a -type d|xargs rm -rf
|
||||
rm -f libphp5.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 php5.spec sapi/apache/libphp5.module buildmk.stamp
|
||||
egrep define'.*include/php' $(top_srcdir)/configure|sed 's/.*>//'|xargs rm -f
|
||||
find . -name Makefile | xargs rm -f
|
||||
|
||||
.PHONY: all clean install distclean test
|
||||
.NOEXPORT:
|
||||
+56
@@ -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:
|
||||
@@ -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
|
||||
+26
-37
@@ -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
|
||||
@@ -29,14 +28,7 @@ Having said that, here are the organizational rules:
|
||||
5. If you don't know how to do something, ask first!
|
||||
|
||||
6. Test your changes before committing them. We mean it. Really.
|
||||
|
||||
Currently we have the following branches in use:
|
||||
HEAD Will become PHP 5.1. This CVS branch is for active development.
|
||||
PHP_5_0 Is used to release the PHP 5.0.x series. Only minor feature
|
||||
enhancements may go in here, but please keep that as infrequent as
|
||||
possible.
|
||||
PHP_4_3 Is used to release the PHP 4.3.x series. Only bugfixes are permitted
|
||||
on this branch.
|
||||
|
||||
|
||||
The next few rules are more of a technical nature.
|
||||
|
||||
@@ -44,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
|
||||
@@ -68,41 +57,41 @@ The next few rules are more of a technical nature.
|
||||
|
||||
The format of the commit messages is pretty simple.
|
||||
|
||||
Use a - to start a new item in your commit message.
|
||||
|
||||
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 the date() function, and in string.c you fixed a
|
||||
memory leak in php_trim(). Don't commit both of these at once. Commit them
|
||||
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
|
||||
a memory leak in php_trim(). Don't commit both of these at once. Commit them
|
||||
separately and try to make sure your commit messages look something like the
|
||||
following.
|
||||
|
||||
For datetime.c:
|
||||
- Added new 'K' format modifier to date() for printing out number of days until
|
||||
New Year's Eve.
|
||||
|
||||
(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:
|
||||
- Fixed a memory leak in php_trim() resulting from improper use of zval_dtor().
|
||||
#- Man, that thing was leaking all over the place!
|
||||
(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 bug #14016 (pgsql notice handler double free crash bug.)
|
||||
|
||||
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.
|
||||
|
||||
@@ -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
-28
@@ -1,7 +1,3 @@
|
||||
(NOTE: you may also want to take a look at the pear package
|
||||
PECL_Gen, a PHP-only alternative for this script that
|
||||
supports way more extension writing tasks and is
|
||||
supposed to replace ext_skel completely in the long run ...)
|
||||
|
||||
WHAT IT IS
|
||||
|
||||
@@ -11,23 +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 and the cat $proto | awk line in
|
||||
ext_skel 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
|
||||
|
||||
@@ -43,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
|
||||
|
||||
@@ -61,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.
|
||||
|
||||
@@ -138,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.
|
||||
@@ -164,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:
|
||||
|
||||
@@ -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, ¶m) == 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;
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
1. strrpos() and strripos() now use the entire string as a needle. Be aware
|
||||
that the existing scripts may no longer work as you expect.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
var_dump(strrpos("ABCDEF","DEF"));
|
||||
var_dump(strrpos("ABCDEF","DAF"));
|
||||
?>
|
||||
|
||||
Will give you different results. The former returns 3 while the latter
|
||||
returns false rather than the position of the last occurrence of 'D'.
|
||||
The same applies to strripos().
|
||||
|
||||
2. Illegal use of string offsets causes E_ERROR instead of E_WARNING.
|
||||
|
||||
EX :
|
||||
<?php
|
||||
$a = "foo";
|
||||
unset($a[0][1][2]);
|
||||
?>
|
||||
|
||||
Fatal error: Cannot use string offset as an array in ... on line 1
|
||||
|
||||
3. array_merge() was changed to accept only arrays. If a non-array variable is
|
||||
passed, a E_WARNING will be thrown for every such parameter. Be careful
|
||||
because your code may start emitting E_WARNING out of the blue.
|
||||
|
||||
4. Be careful when porting from ext/mysql to ext/mysqli. The following
|
||||
functions return NULL when no more data is available in the result set
|
||||
(ext/mysql's functions return FALSE).
|
||||
|
||||
- mysqli_fetch_row()
|
||||
- mysqli_fetch_array()
|
||||
- mysqli_fetch_assoc()
|
||||
|
||||
5. PATH_TRANSLATED server variable is no longer set implicitly under
|
||||
Apache2 SAPI in contrast to the situation in PHP 4, where it is set to the
|
||||
same value as the SCRIPT_FILENAME server variable when it is not populated
|
||||
by Apache. This change was made to comply with the CGI specification.
|
||||
Please refer to bug #23610 for further information.
|
||||
|
||||
6. Starting PHP 5.0.0 the T_ML_CONSTANT constant is no longer defined by the
|
||||
ext/tokenizer extension. If error_reporting is set to E_ALL notices will
|
||||
be produced. Instead of T_ML_CONSTANT for /* */ the T_COMMENT constant
|
||||
is used, thus both // and /* */ are resolved as the T_COMMENT constant.
|
||||
However the PHPDoc style comments /** */ ,which starting PHP 5 are parsed
|
||||
by PHP, are recongnized as T_DOC_COMMENT.
|
||||
|
||||
7. $_SERVER should be populated with argc and argv if variables_order
|
||||
includes "S". If you have specifically configured your system to not
|
||||
create $_SERVER, then of course it shouldn't be there. The change was to
|
||||
always make argc and argv available in the CLI version regardless of the
|
||||
variables_order setting. As in, the CLI version will now always populate
|
||||
the global $argc and $argv variables.
|
||||
|
||||
8. In some cases classes must be declared before used. It only happens only
|
||||
if some of the new features of PHP 5 are used. Otherwise the behaviour is
|
||||
the old.
|
||||
Example 1 (works with no errors):
|
||||
<?php
|
||||
$a = new a();
|
||||
class a {
|
||||
}
|
||||
?>
|
||||
|
||||
Example 2 (throws an error):
|
||||
<?php
|
||||
$a = new a();
|
||||
interface b{
|
||||
}
|
||||
class a implements b {
|
||||
}
|
||||
?>
|
||||
|
||||
Output (example 2) :
|
||||
Fatal error: Class 'a' not found in /tmp/cl.php on line 2
|
||||
|
||||
9. get_class() starting PHP 5 returns the name of the class as it was
|
||||
declared which may lead to problems in older scripts that rely on
|
||||
the previous behaviour - the class name is lowercased. Expect the
|
||||
same behaviour from get_parent_class() when applicable.
|
||||
Example :
|
||||
<?php
|
||||
class FooBar {
|
||||
}
|
||||
class ExtFooBar extends FooBar{}
|
||||
$a = new FooBar();
|
||||
var_dump(get_class($a), get_parent_class($a));
|
||||
?>
|
||||
|
||||
Output (PHP 4):
|
||||
string(6) "foobar"
|
||||
string(9) "extfoobar"
|
||||
|
||||
Output (PHP 5):
|
||||
string(6) "FooBar"
|
||||
string(9) "ExtFooBar"
|
||||
----------------------------------------------------------------------
|
||||
Example code that will break :
|
||||
//....
|
||||
function someMethod($p) {
|
||||
if (get_class($p) != 'helpingclass') {
|
||||
return FALSE;
|
||||
}
|
||||
//...
|
||||
}
|
||||
//...
|
||||
Possible solution is to search for get_class() and get_parent_class() in
|
||||
all your scripts and use strtolower().
|
||||
|
||||
10. get_class_methods() returns the names of the methods of a class as they
|
||||
declared. In PHP4 the names are all lowercased.
|
||||
Example code :
|
||||
<?php
|
||||
class Foo{
|
||||
function doFoo(){}
|
||||
function hasFoo(){}
|
||||
}
|
||||
var_dump(get_class_methods("Foo"));
|
||||
?>
|
||||
Output (PHP4):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "dofoo"
|
||||
[1]=>
|
||||
string(6) "hasfoo"
|
||||
}
|
||||
Output (PHP5):
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(5) "doFoo"
|
||||
[1]=>
|
||||
string(6) "hasFoo"
|
||||
}
|
||||
|
||||
11. Assignment $this is impossible. Starting PHP 5.0.0 $this has special
|
||||
meaning in class methods and is recognized by the PHP parser. The latter
|
||||
will generate a parse error when assignment to $this is found
|
||||
Example code :
|
||||
<?php
|
||||
class Foo {
|
||||
function assignNew($obj) {
|
||||
$this = $obj;
|
||||
}
|
||||
}
|
||||
$a = new Foo();
|
||||
$b = new Foo();
|
||||
$a->assignNew($b);
|
||||
echo "I was executed\n";
|
||||
?>
|
||||
Output (PHP 4):
|
||||
I was executed
|
||||
Output (PHP 5):
|
||||
PHP Fatal error: Cannot re-assign $this in /tmp/this_ex.php on line 4
|
||||
|
||||
@@ -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)
|
||||
|
||||
-379
@@ -1,379 +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);
|
||||
PHPAPI int php_stream_lock(php_stream * stream, int mode);
|
||||
|
||||
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, flock.
|
||||
|
||||
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();
|
||||
|
||||
PHPAPI int php_stream_supports_lock(php_stream * stream);
|
||||
|
||||
This function will return either 1 (success) or 0 (failure) indicating whether or
|
||||
not a lock can be set on this stream. Typically you can only set locks on stdio streams.
|
||||
|
||||
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
|
||||
@@ -1,126 +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 accomplish 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!
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
Failed tests usualy indicate a problem with your local system setup
|
||||
and not within PHP itself (at least for official PHP release versions).
|
||||
You may decide to automaticaly submit a test summary to our QA workflow
|
||||
at the end of a test run.
|
||||
Please do *not* submit a failed test as a bug or ask for help on why
|
||||
it failed on your system without providing substantial backup information
|
||||
on *why* the test failed on your special setup. Thank you :-)
|
||||
|
||||
|
||||
[Testing Basics]
|
||||
----------------
|
||||
The easiest way to test your PHP build is to run "make test" from the
|
||||
command line after successfully compiling. This will run the complete
|
||||
tests for all enabled functionalities and extensions using the PHP
|
||||
CLI binary.
|
||||
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/php5
|
||||
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_INTERACTION=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.
|
||||
See the HOWTO at http://qa.php.net/write-test.php
|
||||
|
||||
|
||||
[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);
|
||||
|
||||
?>
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
This is an addendum to README.TESTING with additional information
|
||||
specific to run-tests2.php.
|
||||
|
||||
run-tests2.php is backward compatible with tests developed for
|
||||
the original run-tests.php script. run-tests2 is *not* used by
|
||||
'make test'. run-tests2 was developed to provide support for
|
||||
testing PHP under it's primary environment, HTTP, and can run the
|
||||
PHP tests under any of the SAPI modules that are direct executables,
|
||||
or are accessable via HTTP.
|
||||
|
||||
[New features]
|
||||
----------------
|
||||
* Command line interface:
|
||||
You can run 'php run-tests2.php -h' to get all the possible options.
|
||||
* Configuration file:
|
||||
the -c argument will allow you to use a configuration file. This is
|
||||
handy if you are testing multiple environments and need various options
|
||||
depending on the environment.
|
||||
see run-tests-config.php for details.
|
||||
* CGI Emulation:
|
||||
Will emulate a CGI environment when testing with the cgi sapi executable.
|
||||
* HTTP testing:
|
||||
can be configured to run test scripts through an HTTP server running
|
||||
on localhost. localhost is required since either the web server must
|
||||
alias a directory to the php source directory, or the test scripts
|
||||
must be copied to a directory under the web server
|
||||
(see config options TEST_WEB_BASE_URL, TEST_BASE_PATH, and TEST_WEB_EXT)
|
||||
* New sections supported for test files (see below)
|
||||
|
||||
When running tests over http, tests that require ini settings different that what
|
||||
the web server runs under will be skipped. Since the test harness defines a number
|
||||
of ini settings by default, the web server may require special configuration to
|
||||
make testing work.
|
||||
|
||||
[Example Usage]
|
||||
----------------
|
||||
Some (but not all!) examples of usage:
|
||||
|
||||
1. run tests from the php source directory
|
||||
php run-tests2.php -p /path/to/php-cli
|
||||
|
||||
2. run tests using cgi emulation
|
||||
php run-tests2.php -p /path/to/php-cgi
|
||||
|
||||
3. run tests over http, copying test files into document root
|
||||
php run-tests2.php -w -u http://localhost/test -m /path/to/htdocs/test
|
||||
|
||||
4. run tests over http, php sources have been aliased in web server
|
||||
php run-tests2.php -w -u http://localhost/test
|
||||
|
||||
5. run tests using configuration file
|
||||
php run-tests2.php -c /path/to/run-tests-config.php
|
||||
|
||||
6. run tests using configuration file, but overriding some settings:
|
||||
(config file must be first)
|
||||
php run-tests2.php -c /path/to/run-tests-config.php -w -t 3 -d /path/to/testdir
|
||||
|
||||
NOTE: configuration as described in README.TESTING still works.
|
||||
|
||||
[New Test Sections]
|
||||
----------------
|
||||
In addition to the traditional test sections
|
||||
(see http://qa.php.net/write-test.php), several new sections are available
|
||||
under run-tests2.
|
||||
|
||||
--POST--
|
||||
This is not a new section, but not multipart posts are supported for testing
|
||||
file uploads, or other types of POST data.
|
||||
|
||||
--CGI--
|
||||
This section takes no value. It merely provides a simple marker for tests
|
||||
that MUST be run as CGI, even if there is no --POST-- or --GET-- sections
|
||||
in the test file.
|
||||
|
||||
--DESCRIPTION--
|
||||
Not used for anything, just a section for documenting the test
|
||||
|
||||
--ENV--
|
||||
This section get's eval()'d to help build an environment for the
|
||||
execution of the test. This can be used to change environment
|
||||
vars that are used for CGI emulation, or simply to set env vars
|
||||
for cli testing. A full example looks like:
|
||||
|
||||
--ENV--
|
||||
return <<<END
|
||||
PATH_TRANSLATED=$filename
|
||||
PATH_INFO=$scriptname
|
||||
SCRIPT_NAME=$scriptname
|
||||
END;
|
||||
|
||||
Some variables are made easily available for use in this section, they
|
||||
include:
|
||||
$filename full native path to file, will become PATH_TRANSLATED
|
||||
$filepath =dirname($filename)
|
||||
$scriptname this is what will become SCRIPT_NAME unless you override it
|
||||
$docroot the equivelant of DOCUMENT_ROOT under Apache
|
||||
$cwd the directory that the test is being initiated from
|
||||
$this->conf all run-tests2 configuration vars
|
||||
$this->env all environment variables that will get passed to the test
|
||||
|
||||
|
||||
--REQUEST--
|
||||
This section is also eval'd, and is similar in nature to --ENV--. However,
|
||||
this section is used to build the url used in an HTTP request. Valid values
|
||||
to set in this section would include:
|
||||
SCRIPT_NAME The inital part of the request url
|
||||
PATH_INFO The pathinfo part of a request url
|
||||
FRAGMENT The fragment section of a url (after #)
|
||||
QUERY_STRING The query part of a url (after ?)
|
||||
|
||||
--REQUEST--
|
||||
return <<<END
|
||||
PATH_INFO=/path/info
|
||||
END;
|
||||
|
||||
--HEADERS--
|
||||
This section is also eval'd. It is used to provide additional headers sent
|
||||
in an HTTP request, such as content type for multipart posts, cookies, etc.
|
||||
|
||||
--HEADERS--
|
||||
return <<<END
|
||||
Content-Type=multipart/form-data; boundary=---------------------------240723202011929
|
||||
Content-Length=100
|
||||
END;
|
||||
|
||||
--EXPECTHEADERS--
|
||||
This section can be used to define what headers are required to be
|
||||
received back from a request, and is checked in addition to the
|
||||
regular expect sections. For example:
|
||||
|
||||
--EXPECTHEADERS--
|
||||
Status: 404
|
||||
|
||||
|
||||
|
||||
@@ -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_php5.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.
|
||||
@@ -1,174 +0,0 @@
|
||||
The Win32 Build System.
|
||||
$Id$
|
||||
Wez Furlong <wez@thebrainroom.com>
|
||||
|
||||
If you need help with the build system, send mail to
|
||||
internals@lists.php.net; please don't email me directly.
|
||||
|
||||
===========================================================
|
||||
Contents:
|
||||
1. How to build PHP under windows
|
||||
a. Requirements
|
||||
b. Opening a command prompt
|
||||
c. Generating configure.js
|
||||
d. Configuring
|
||||
e. Building
|
||||
f. Cleaning up
|
||||
g. Running the test suite
|
||||
h. snapshot building
|
||||
|
||||
2. How to write config.w32 files
|
||||
x. to be written.
|
||||
|
||||
===========================================================
|
||||
1. How to build PHP under windows
|
||||
a. Requirements
|
||||
|
||||
You need:
|
||||
- Windows Scripting Host (cscript.exe)
|
||||
- Microsoft Build Tools from:
|
||||
Microsoft Visual Studio (VC6) or later
|
||||
|
||||
You also need:
|
||||
- bindlib_w32 [http://www.php.net/extra/bindlib_w32.zip]
|
||||
- win32build [http://www.php.net/extra/win32build.zip]
|
||||
|
||||
b. Opening the Build Environment Command Prompt:
|
||||
- Using Visual Studio (VC6)
|
||||
1. Install it
|
||||
2. If you have a VC++ Command Prompt icon on your start menu,
|
||||
click on it to get a Command Prompt with the env vars
|
||||
set up correctly.
|
||||
|
||||
If not, create a new shortcut and set the Target to:
|
||||
|
||||
%comspec% /k "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
|
||||
|
||||
You might also want to set the prompt to start in
|
||||
a convenient location (such as the root of your
|
||||
PHP source checkout).
|
||||
|
||||
- Using Visual Studio .Net
|
||||
1. Install it.
|
||||
2. Under the Visual Studio .Net Tools sub menu of your start
|
||||
menu, you should have a Visual Studio .Net Command Prompt
|
||||
icon. If not, create a new shortcut and set the Target to:
|
||||
|
||||
%comspec% /k "C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat"
|
||||
|
||||
You might also want to set the prompt to start in
|
||||
a convenient location (such as the root of your
|
||||
PHP source checkout).
|
||||
|
||||
- Using the Platform SDK tools
|
||||
1. Download the Platform SDK:
|
||||
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
|
||||
|
||||
- You need the Core SDK, which is approx 200MB to download
|
||||
and requires approx 500MB of disk space.
|
||||
- The other components of the SDK are not required by PHP
|
||||
- You might be able to reduce the download size by downloading
|
||||
the installer control component first and then selecting
|
||||
only the Build Environment (around 30MB), but I haven't
|
||||
tried this.
|
||||
|
||||
** Note: it seems that MS don't include the 32 bit
|
||||
build tools in the platform SDK any longer, so
|
||||
you will probably have very limited luck if you
|
||||
don't also have VC++ or VS.Net already installed.
|
||||
|
||||
2. Once installed, you will have an icon on your start menu
|
||||
that will launch the build environment; the latest SDK's
|
||||
install a number of different versions of this; you probably
|
||||
want to choose the Windows 2000 Retail build environment.
|
||||
Clicking on this will open a command prompt with its Path,
|
||||
Include and Lib env vars set to point to the build tools
|
||||
and win32 headers.
|
||||
|
||||
c. Generating configure
|
||||
|
||||
Change directory to where you have your PHP 5 sources.
|
||||
Run buildconf.bat.
|
||||
|
||||
d. Configuring
|
||||
|
||||
cscript /nologo configure.js --help
|
||||
|
||||
Will give you a list of configuration options; these will
|
||||
have the form:
|
||||
|
||||
--enable-foo or --disable-foo or --with-foo or --without-foo.
|
||||
|
||||
--enable-foo will turn something on, and is equivalent to
|
||||
specifying --enable-foo=yes
|
||||
|
||||
--disable-foo will turn something off, and is equivalent to
|
||||
specifying --enable-foo=no
|
||||
|
||||
--enable-foo=shared will attempt to build that feature as
|
||||
a shared, dynamically loadable module.
|
||||
|
||||
Sometimes a configure option needs additional information
|
||||
about where to find headers and libraries; quite often
|
||||
you can specify --enable-foo=option where option could be
|
||||
the path to where to find those files. If you want to
|
||||
specify a parameter and build it as shared, you can use
|
||||
this syntax instead: --enable-foo=shared,option
|
||||
|
||||
The same rules all apply to --with-foo and --without-foo;
|
||||
the only difference is the way the options are named;
|
||||
the convention is that --enable-foo means that you are
|
||||
switching on something that comes with PHP, whereas
|
||||
--with-foo means that you want to build in something
|
||||
external to PHP.
|
||||
|
||||
e. Building
|
||||
|
||||
Once you have successfully configured your build (make
|
||||
sure you read the output from the command to make sure
|
||||
it worked correctly), you can build the code; simply type
|
||||
|
||||
"nmake" at the command prompt, and it will build everthing
|
||||
you asked for.
|
||||
|
||||
Once the build has completed, you will find your binaries
|
||||
in the build dir determined by configure; this is typically
|
||||
Release_TS for release builds or Debug_TS for debug builds.
|
||||
If you build a non-thread-safe build, it will use Release
|
||||
or Debug to store the files. Also in this build dir you
|
||||
will find sub directories for each module that went into
|
||||
your PHP build. The files you'll want to keep are the
|
||||
.exe and .dll files directly in your build dir.
|
||||
|
||||
f. Cleaning Up
|
||||
|
||||
You can automatically delete everything that was built
|
||||
by running "nmake clean". This will delete everything
|
||||
that was put there when you ran nmake, including the
|
||||
.exe and .dll files.
|
||||
|
||||
g. Running the test suite
|
||||
|
||||
You can verify that your build is working well by running
|
||||
the regression test suite. You do this by typing
|
||||
"nmake test". You can specify the tests you want to run
|
||||
by defing the TESTS variable - if you wanted to run the
|
||||
sqlite test suite only, you would type
|
||||
"nmake /D TESTS=ext/sqlite/tests test"
|
||||
|
||||
h. Snapshot Building
|
||||
|
||||
If you want to set up an automated build that will tolerate
|
||||
breakages in some of the modules, you can use the
|
||||
--enable-snapshot-build configure option to generate a
|
||||
makefile optimized for that purpose. A snapshot build will
|
||||
switch the argument parser so that the default option for
|
||||
configure switches that your don't specify will be set
|
||||
to "shared". The effect of this is to turn on all options
|
||||
unless you explicitly disable them. When you have configured
|
||||
your snapshot build, you can use "nmake build-snap" to build
|
||||
everything, ignoring build errors in individual extensions
|
||||
or SAPI.
|
||||
|
||||
vim:tw=78:sw=1:ts=1:et
|
||||
|
||||
+83
-93
@@ -1,112 +1,102 @@
|
||||
Using PHP 5 with the Zeus Web Server
|
||||
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 CGI/FastCGI with Zeus
|
||||
-----------------------------------------------
|
||||
To build the ISAPI version of PHP, start the configuration with:
|
||||
|
||||
Step 1 - Compile PHP as FastCGI.
|
||||
./configure --with-zeus=/usr/local/zeus
|
||||
|
||||
Compile as follows:
|
||||
./configure --enable-fastcgi
|
||||
make
|
||||
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.
|
||||
|
||||
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)
|
||||
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.
|
||||
|
||||
|
||||
Step 2 - configure Zeus
|
||||
Configuring the webserver
|
||||
-------------------------
|
||||
|
||||
Four stages:
|
||||
- enable FastCGI
|
||||
- configure FastCGI
|
||||
- setup alias for FastCGI
|
||||
- setup alias for PHP
|
||||
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:
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
Finally restart your virtual server for these changes to take effect.
|
||||
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 - start PHP as a FastCGI runner
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
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:
|
||||
*) Why does the compile fail at Zend/zend-scanner-cc.cc
|
||||
or Zend/zend-parser.c ?
|
||||
|
||||
PHP_FCGI_CHILDREN - the number of child processes to pre-fork. This
|
||||
variable MUST be set, if not then the PHP will not run as a FastCGI.
|
||||
We recommend a value of 8 for a fairly busy site. If you have many,
|
||||
long-running PHP scripts, then you may need to increase this further.
|
||||
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:
|
||||
|
||||
PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
|
||||
handles before exiting. If not set, defaults to 500.
|
||||
bison 1.28 or later
|
||||
flex 2.5.4 or later
|
||||
|
||||
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.
|
||||
*) Why does my PHP library fail to load?
|
||||
|
||||
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'
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
For more information and help with Zeus, please visit our website:
|
||||
http://www.zeus.com
|
||||
@@ -1,193 +0,0 @@
|
||||
Input Filter Support in PHP 5
|
||||
-----------------------------
|
||||
|
||||
XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
|
||||
and can be quite difficult to prevent. Whenever you accept user data
|
||||
and somehow display this data back to users, you are likely vulnerable
|
||||
to XSS hacks.
|
||||
|
||||
The Input Filter support in PHP 5 is aimed at providing the framework
|
||||
through which a company-wide or site-wide security policy can be
|
||||
enforced. It is implemented as a SAPI hook and is called from the
|
||||
treat_data and post handler functions. To implement your own security
|
||||
policy you will need to write a standard PHP extension.
|
||||
|
||||
A simple implementation might look like the following. This stores the
|
||||
original raw user data and adds a my_get_raw() function while the normal
|
||||
$_POST, $_GET and $_COOKIE arrays are only populated with stripped
|
||||
data. In this simple example all I am doing is calling strip_tags() on
|
||||
the data. If register_globals is turned on, the default globals that
|
||||
are created will be stripped ($foo) while a $RAW_foo is created with the
|
||||
original user input.
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
|
||||
zval *post_array;
|
||||
zval *get_array;
|
||||
zval *cookie_array;
|
||||
ZEND_END_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
#ifdef ZTS
|
||||
#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
|
||||
#else
|
||||
#define IF_G(v) (my_input_filter_globals.v)
|
||||
#endif
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
|
||||
|
||||
function_entry my_input_filter_functions[] = {
|
||||
PHP_FE(my_get_raw, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
zend_module_entry my_input_filter_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"my_input_filter",
|
||||
my_input_filter_functions,
|
||||
PHP_MINIT(my_input_filter),
|
||||
PHP_MSHUTDOWN(my_input_filter),
|
||||
NULL,
|
||||
PHP_RSHUTDOWN(my_input_filter),
|
||||
PHP_MINFO(my_input_filter),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
PHP_MINIT_FUNCTION(my_input_filter)
|
||||
{
|
||||
ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
|
||||
|
||||
REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
sapi_register_input_filter(my_sapi_input_filter);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_RSHUTDOWN_FUNCTION(my_input_filter)
|
||||
{
|
||||
if(IF_G(get_array)) {
|
||||
zval_ptr_dtor(&IF_G(get_array));
|
||||
IF_G(get_array) = NULL;
|
||||
}
|
||||
if(IF_G(post_array)) {
|
||||
zval_ptr_dtor(&IF_G(post_array));
|
||||
IF_G(post_array) = NULL;
|
||||
}
|
||||
if(IF_G(cookie_array)) {
|
||||
zval_ptr_dtor(&IF_G(cookie_array));
|
||||
IF_G(cookie_array) = NULL;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
PHP_MINFO_FUNCTION(my_input_filter)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
|
||||
php_info_print_table_row( 2, "Revision", "$Revision$");
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
/* The filter handler. If you return 1 from it, then PHP also registers the
|
||||
* (modified) variable. Returning 0 prevents PHP from registering the variable;
|
||||
* you can use this if your filter already registers the variable under a
|
||||
* different name, or if you just don't want the variable registered at all. */
|
||||
SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
|
||||
{
|
||||
zval new_var;
|
||||
zval *array_ptr = NULL;
|
||||
char *raw_var;
|
||||
int var_len;
|
||||
|
||||
assert(*val != NULL);
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
if(!IF_G(get_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(get_array) = array_ptr;
|
||||
break;
|
||||
case PARSE_POST:
|
||||
if(!IF_G(post_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(post_array) = array_ptr;
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
if(!IF_G(cookie_array)) {
|
||||
ALLOC_ZVAL(array_ptr);
|
||||
array_init(array_ptr);
|
||||
INIT_PZVAL(array_ptr);
|
||||
}
|
||||
IF_G(cookie_array) = array_ptr;
|
||||
break;
|
||||
}
|
||||
Z_STRLEN(new_var) = val_len;
|
||||
Z_STRVAL(new_var) = estrndup(*val, val_len);
|
||||
Z_TYPE(new_var) = IS_STRING;
|
||||
|
||||
var_len = strlen(var);
|
||||
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len+5);
|
||||
|
||||
php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
|
||||
|
||||
php_strip_tags(*val, val_len, NULL, NULL, 0);
|
||||
|
||||
*new_val_len = strlen(*val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PHP_FUNCTION(my_get_raw)
|
||||
{
|
||||
long arg;
|
||||
char *var;
|
||||
int var_len;
|
||||
zval **tmp;
|
||||
zval *array_ptr = NULL;
|
||||
HashTable *hash_ptr;
|
||||
char *raw_var;
|
||||
|
||||
if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(arg) {
|
||||
case PARSE_GET:
|
||||
array_ptr = IF_G(get_array);
|
||||
break;
|
||||
case PARSE_POST:
|
||||
array_ptr = IF_G(post_array);
|
||||
break;
|
||||
case PARSE_COOKIE:
|
||||
array_ptr = IF_G(post_array);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!array_ptr) RETURN_FALSE;
|
||||
|
||||
/*
|
||||
* I'm changing the variable name here because when running with register_globals on,
|
||||
* the variable will end up in the global symbol table
|
||||
*/
|
||||
raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
|
||||
strcpy(raw_var, "RAW_");
|
||||
strlcat(raw_var,var,var_len+5);
|
||||
hash_ptr = HASH_OF(array_ptr);
|
||||
|
||||
if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
|
||||
*return_value = **tmp;
|
||||
zval_copy_ctor(return_value);
|
||||
} else {
|
||||
RETVAL_FALSE;
|
||||
}
|
||||
efree(raw_var);
|
||||
}
|
||||
|
||||
@@ -3,145 +3,101 @@ parenthesis means that person has taken on this project.
|
||||
|
||||
Zend
|
||||
----
|
||||
* 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.
|
||||
* 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?)
|
||||
* 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.
|
||||
|
||||
* allow foreach ($array as $k => &$val) syntax. right now we cannot
|
||||
traverse an array without copying each element.
|
||||
* look at replacing c-lib call tolower().
|
||||
* make hash API functions work with HASH_OF() to save time.
|
||||
|
||||
global
|
||||
------
|
||||
* 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.
|
||||
* on some platforms unimplemented function will just do nothing
|
||||
(e.g. symlink) they should print a warning or not even be defined!
|
||||
(DONE ?)
|
||||
* 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 (seems to be done?).
|
||||
* 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.
|
||||
|
||||
Streams
|
||||
-------
|
||||
* Route filestat.c through the wrapper layer; isolate the statcache code
|
||||
so that it is independent of php functions and can be applied to any
|
||||
stream/path.
|
||||
* Implement generalized connection pool for stated protocols such as
|
||||
ftp and http/1.1 (using keep-alive) to avoid having to negotiate
|
||||
new command/request stream for each subsequent call; Possibly store
|
||||
resources in contexts (creating a default context if necessary) to
|
||||
allow segmentation of connection pools.
|
||||
* Add a method to take ownership of the memory buffer in memory streams so
|
||||
that generating string values for zvals doesn't require an estrdup.
|
||||
* bundle and use curl lib for fopen wrapper.
|
||||
* 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/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.
|
||||
* 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)
|
||||
@@ -151,5 +107,3 @@ ext/wddx
|
||||
other cool stuff
|
||||
----------------
|
||||
* PVM extension
|
||||
|
||||
vim:et:sw=4:ts=4
|
||||
@@ -1,17 +0,0 @@
|
||||
Zend Engine
|
||||
-----------
|
||||
- Look at making zend_constant value member be a zval* instead of zval. (Andi)
|
||||
- Add the patch for referring to existing .ini vars in .ini files. (Andrei)
|
||||
- Implement inheritance rules for type hints. (Marcus)
|
||||
- Implement true/false/NULL as keywords (apply the patch). (Andi, Marcus)
|
||||
- Implement typehinting for arrays (apply the patch). (Andi, Marcus)
|
||||
- Find a keyword for the if-set-or operator (apply the patch). (Marcus, all)
|
||||
- Fix ZTS destruction (apply the patch). (Marcus)
|
||||
|
||||
Build System
|
||||
------------
|
||||
- Implement load order of built-in extensions (apply the patch). (Wez)
|
||||
|
||||
Standard Library
|
||||
----------------
|
||||
- Implement new time/date parsing and handling functions. (Derick)
|
||||
@@ -1,109 +0,0 @@
|
||||
Component: Zend Engine 2
|
||||
|
||||
Important stuff to finish: PPP members/PPP methods,
|
||||
support of overloaded extensions, possibly differentiate
|
||||
between class and namespace as discussed with Stig in
|
||||
Germany.
|
||||
Responsibility: Zeev, Andi, Stas
|
||||
Time frame: Couple of months for first part and extensions will be
|
||||
ongoing while PHP is being fixed.
|
||||
Things to leave for later versions: Native aggregation
|
||||
support, accessing static members via object and not class.
|
||||
|
||||
|
||||
Component: Aggregation
|
||||
Responsibility: Andi, Stig?
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: Redesign of API Versioning
|
||||
Responsibility: ?
|
||||
Time frame: 1 month
|
||||
|
||||
|
||||
Component: Thread Safety
|
||||
Identify the extensions that are not thread safe by design
|
||||
or due to dependant libraries and identify them as such.
|
||||
If possible try to resolve thread safety issue via code
|
||||
improvements (if php code or patches will be accepted by
|
||||
library maintainers). For situations where thread safety
|
||||
cannot easily be acheived a flag in the extension API is
|
||||
set so PHP can identify non-thread safe extensions. These
|
||||
extensions will not be loaded in a ZTS compiled binary
|
||||
(unless it is cli/cgi).
|
||||
|
||||
Responsibility: ?
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: SAPI
|
||||
Environment variables defined in the CGI spec need to be
|
||||
verified in each SAPI module that they conform to the CGI
|
||||
spec correctly. If they do not, the SAPI module needs to
|
||||
fix the variable prior to script execution. Having this
|
||||
conformity will aid in having PHP scripts run correctly
|
||||
under different sapi modules.
|
||||
|
||||
Responsibility: Shane Caraveo & each sapi module owner
|
||||
Timeframe: ? (but shouldn't be much effort, most modules are probably ok)
|
||||
|
||||
|
||||
Component: Input Filtering
|
||||
- Implement a SAPI input filter hook that will get called
|
||||
just before registering a variable in the
|
||||
treat_data/post_handler hooks. (done)
|
||||
- Make sure this is also done in mbstring (done)
|
||||
- Provide access functions, or perhaps a new
|
||||
$_RAW_GET/POST/Cookie set of superglobals to get at the
|
||||
unfiltered data
|
||||
- Provide a .ini directive which allows people to set their
|
||||
input filter to one of the built-in strip_tags,
|
||||
htmlspecialchars or whatever other internal function might
|
||||
be useful here.
|
||||
- (The main benefit of this is to make it easier for people
|
||||
to solve the XSS problem once and for all without having
|
||||
to go through every line of their code and adding input
|
||||
validation/filtering everywhere)
|
||||
Responsibility: Rasmus
|
||||
Timeframe: Yesterday
|
||||
|
||||
|
||||
Component: RPC Abstraction Layer
|
||||
Porting java, com, dotnet, xmlrpc, corba, soap and python, srm
|
||||
(are there more ?) to work with the new oo api and preferably
|
||||
by using ext/rpc.
|
||||
Responsibility: Harald
|
||||
Time frame: 2 months (but i have to wait for a few engine features first)
|
||||
|
||||
|
||||
Component: OO Extensions
|
||||
Each OO extension has to be revised and rewritten to fit into
|
||||
the new OO model. We should decide which extensions are a must
|
||||
to have for the release and which can be ported by the maintainer
|
||||
later as a separate pecl release.
|
||||
A list of extensions to be extended that have to be investigated:
|
||||
* browscap
|
||||
* aggregate
|
||||
* all *sql extensions (*_fetch_object)
|
||||
* domxml (seems like christian is rewriting it anyways)
|
||||
* ming
|
||||
Responsibility: Harald (, extension maintainers)
|
||||
|
||||
|
||||
Component: Abstract Data Types (ADT)
|
||||
Responsibility: Sterling, Harald
|
||||
Time frame: ?
|
||||
|
||||
|
||||
Component: Test Suite
|
||||
Extending the test suite with atleast a test for every
|
||||
function in an extension that doesn't require external
|
||||
resources. Also developing an automated test thing which
|
||||
cvs ups's, compiles and tests the build on a daily base on
|
||||
as much platforms/extensions as possible.
|
||||
|
||||
The test suite will also be extended to support threaded
|
||||
testing and testing for differing sapi modules (via http
|
||||
calls or other methods).
|
||||
Reponsibility: Derick (, extension maintainers)
|
||||
Time frame: 3 months
|
||||
@@ -1,3 +0,0 @@
|
||||
- clean up .cvsignores
|
||||
- purge Makefile.ins and replace PHP_EXTENSION in config.m4s
|
||||
with appropiate calls to PHP_NEW_EXTENSION
|
||||
+77
-289
@@ -15,6 +15,7 @@
|
||||
#ifdef ZTS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
@@ -34,97 +35,40 @@ typedef struct {
|
||||
size_t size;
|
||||
ts_allocate_ctor ctor;
|
||||
ts_allocate_dtor dtor;
|
||||
#ifdef MBO_0
|
||||
int done;
|
||||
#endif
|
||||
} tsrm_resource_type;
|
||||
|
||||
|
||||
/* 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;
|
||||
@@ -132,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;
|
||||
}
|
||||
|
||||
@@ -142,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;
|
||||
}
|
||||
|
||||
@@ -160,15 +104,8 @@ TSRM_API void tsrm_shutdown(void)
|
||||
int j;
|
||||
|
||||
next_p = p->next;
|
||||
for (j=0; j<p->count; j++) {
|
||||
if (p->storage[j]) {
|
||||
#ifdef MBO_0
|
||||
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
#endif
|
||||
free(p->storage[j]);
|
||||
}
|
||||
for (j=0; j<id_count; j++) {
|
||||
free(p->storage[j]);
|
||||
}
|
||||
free(p->storage);
|
||||
free(p);
|
||||
@@ -176,59 +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;
|
||||
#ifdef MBO_0
|
||||
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
|
||||
#endif
|
||||
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++) {
|
||||
@@ -242,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;
|
||||
@@ -252,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,46 +182,26 @@ 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++) {
|
||||
#if MBO_0
|
||||
if (resource_types_table[i].done) {
|
||||
(*thread_resources_ptr)->storage[i] = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
(*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);
|
||||
}
|
||||
(*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]);
|
||||
}
|
||||
}
|
||||
|
||||
if (tsrm_new_thread_end_handler) {
|
||||
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
tsrm_new_thread_end_handler(thread_id);
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
@@ -310,47 +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;
|
||||
|
||||
#ifdef NETWARE
|
||||
/* The below if loop is added for NetWare to fix an abend while unloading PHP
|
||||
* when an Apache unload command is issued on the system console.
|
||||
* While exiting from PHP, at the end for some reason, this function is called
|
||||
* with tsrm_tls_table = NULL. When this happened, the server abends when
|
||||
* tsrm_tls_table is accessed since it is NULL.
|
||||
*/
|
||||
if(tsrm_tls_table) {
|
||||
#endif
|
||||
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);
|
||||
@@ -358,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) {
|
||||
@@ -368,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;
|
||||
@@ -376,25 +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);
|
||||
#ifdef NETWARE
|
||||
} /* if(tsrm_tls_table) */
|
||||
#endif
|
||||
|
||||
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);
|
||||
@@ -403,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;
|
||||
}
|
||||
@@ -437,36 +298,6 @@ void ts_free_thread(void)
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{
|
||||
#ifdef MBO_0
|
||||
int i;
|
||||
int j = TSRM_UNSHUFFLE_RSRC_ID(id);
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Freeing resource id %d", id));
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count > j && p->storage[j]) {
|
||||
if (resource_types_table && resource_types_table[j].dtor) {
|
||||
resource_types_table[j].dtor(p->storage[j], &p->storage);
|
||||
}
|
||||
free(p->storage[j]);
|
||||
p->storage[j] = NULL;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
resource_types_table[j].done = 1;
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -489,20 +320,17 @@ 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;
|
||||
MUTEX_T mutexp;
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
||||
@@ -514,27 +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(GNUPTH)
|
||||
free(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
@@ -543,24 +364,21 @@ 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;
|
||||
@@ -572,20 +390,16 @@ 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;
|
||||
@@ -597,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;
|
||||
|
||||
@@ -616,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;
|
||||
|
||||
@@ -630,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
@@ -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
|
||||
+26
-73
@@ -13,16 +13,31 @@
|
||||
#ifndef TSRM_H
|
||||
#define TSRM_H
|
||||
|
||||
/* #ifndef WIN32 */
|
||||
#ifndef WIN32
|
||||
# include <tsrm_config.h>
|
||||
#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,27 +48,6 @@
|
||||
# define TSRM_API
|
||||
#endif
|
||||
|
||||
/* Only compile multi-threading functions if we're in ZTS mode */
|
||||
#ifdef ZTS
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <shellapi.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
|
||||
@@ -71,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
|
||||
|
||||
@@ -93,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);
|
||||
@@ -111,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);
|
||||
@@ -129,35 +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 TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
|
||||
#define TSRMLS_SET_CTX(ctx) (void ***) ctx = tsrm_ls
|
||||
#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_FETCH_FROM_CTX(ctx)
|
||||
#define TSRMLS_SET_CTX(ctx)
|
||||
#define TSRMLS_D void
|
||||
#define TSRMLS_DC
|
||||
#define TSRMLS_C
|
||||
#define TSRMLS_CC
|
||||
|
||||
#endif /* ZTS */
|
||||
|
||||
#endif /* TSRM_H */
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// vim:ft=javascript
|
||||
// $Id$
|
||||
|
||||
if (CHECK_HEADER_ADD_INCLUDE("NewAPIs.h", "CFLAGS_PHP", php_usual_include_suspects)) {
|
||||
// Need to add the flag directly, since TSRM doesn't include the config
|
||||
// header
|
||||
ADD_FLAG("CFLAGS_PHP", "/DHAVE_NEWAPIS_H=1");
|
||||
}
|
||||
ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c");
|
||||
|
||||
+3
-1
@@ -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)
|
||||
+39
-55
@@ -30,28 +30,25 @@ dnl PTHREADS_FLAGS
|
||||
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
|
||||
AC_DEFUN(PTHREADS_FLAGS,[
|
||||
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
|
||||
@@ -65,7 +62,7 @@ dnl PTHREADS_CHECK_COMPILE
|
||||
dnl
|
||||
dnl Check whether the current setup can use POSIX threads calls
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK_COMPILE], [
|
||||
AC_DEFUN(PTHREADS_CHECK_COMPILE, [
|
||||
AC_TRY_RUN( [
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
@@ -80,19 +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
|
||||
], [
|
||||
dnl For cross compiling running this test is of no use. NetWare supports pthreads
|
||||
pthreads_working=no
|
||||
case $host_alias in
|
||||
*netware*)
|
||||
pthreads_working=yes
|
||||
esac
|
||||
]
|
||||
) ] )dnl
|
||||
pthreads_working="no"
|
||||
], pthreads_working="no" ) ] )dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK()
|
||||
dnl
|
||||
@@ -108,46 +97,41 @@ dnl -pthreads gcc (Solaris)
|
||||
dnl -qthreaded AIX cc V5
|
||||
dnl -threads gcc (HP-UX)
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_CHECK],[
|
||||
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
|
||||
@@ -155,14 +139,14 @@ 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
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_ASSIGN_VARS],[
|
||||
AC_DEFUN(PTHREADS_ASSIGN_VARS,[
|
||||
if test -n "$ac_cv_pthreads_lib"; then
|
||||
LIBS="$LIBS -l$ac_cv_pthreads_lib"
|
||||
fi
|
||||
|
||||
+14
-45
@@ -1,6 +1,6 @@
|
||||
|
||||
dnl TSRM_CHECK_GCC_ARG(ARG, ACTION-IF-FOUND, ACTION-IF-NOT_FOUND)
|
||||
AC_DEFUN([TSRM_CHECK_GCC_ARG],[
|
||||
AC_DEFUN(TSRM_CHECK_GCC_ARG,[
|
||||
gcc_arg_name=[ac_cv_gcc_arg]translit($1,A-Z-,a-z_)
|
||||
AC_CACHE_CHECK([whether $CC supports $1], [ac_cv_gcc_arg]translit($1,A-Z-,a-z_), [
|
||||
echo 'void somefunc() { };' > conftest.c
|
||||
@@ -21,7 +21,7 @@ AC_DEFUN([TSRM_CHECK_GCC_ARG],[
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([TSRM_BASIC_CHECKS],[
|
||||
AC_DEFUN(TSRM_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
dnl AC_REQUIRE([AM_PROG_CC_STDC])dnl
|
||||
@@ -33,7 +33,7 @@ AC_CHECK_HEADERS(stdarg.h)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_CHECK_PTH],[
|
||||
AC_DEFUN(TSRM_CHECK_PTH,[
|
||||
|
||||
AC_MSG_CHECKING(for GNU Pth)
|
||||
PTH_PREFIX="`$1 --prefix`"
|
||||
@@ -50,65 +50,36 @@ 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],[
|
||||
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)
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([TSRM_THREADS_CHECKS],[
|
||||
AC_DEFUN(TSRM_THREADS_CHECKS,[
|
||||
|
||||
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
|
||||
|
||||
@@ -1,11 +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
|
||||
@@ -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
|
||||
|
||||
@@ -5,30 +5,19 @@
|
||||
# define TSRM_WIN32
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include "tsrm_config.w32.h"
|
||||
#else
|
||||
# include <tsrm_config.h>
|
||||
#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 */
|
||||
# ifndef NETWARE
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
|
||||
-240
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.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> |
|
||||
| Anantha Kesari H Y <hyanantha@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
|
||||
*/
|
||||
#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);
|
||||
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);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#elif defined(USE_MKFIFO)
|
||||
pipe_handle = mkfifo(filePath, mode);
|
||||
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);
|
||||
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);
|
||||
if (err) {
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Separate commandline string into words */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 'ssHandle' is not a struct/union/class member */
|
||||
/*
|
||||
envSpec.esStdin.ssHandle =
|
||||
envSpec.esStdout.ssHandle =
|
||||
envSpec.esStderr.ssHandle = -1;
|
||||
*/
|
||||
envSpec.esStdin.ssPathCtx = NULL;
|
||||
envSpec.esStdout.ssPathCtx = NULL;
|
||||
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; */ /* 'ssHandle' is not a struct/union/class member */
|
||||
nameSpec.ssPathCtx = NULL; /* Not used */
|
||||
nameSpec.ssPath = argv[0];
|
||||
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
|
||||
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]);
|
||||
}
|
||||
|
||||
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 /* NETWARE */
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.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> |
|
||||
| Anantha Kesari H Y <hyanantha@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TSRM_NW_H
|
||||
#define TSRM_NW_H
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
TSRM_API FILE* popen(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE* stream);
|
||||
|
||||
#endif
|
||||
+178
-348
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP version 4.0 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| 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 through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| 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. |
|
||||
@@ -33,28 +33,16 @@
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <io.h>
|
||||
#include "tsrm_win32.h"
|
||||
# if HAVE_NEWAPIS_H
|
||||
# define WANT_GETLONGPATHNAME_WRAPPER
|
||||
# define COMPILE_NEWAPIS_STUBS
|
||||
# include <NewAPIs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
#include <fsio.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
|
||||
|
||||
@@ -81,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)
|
||||
@@ -96,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 "/"
|
||||
@@ -115,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 */
|
||||
@@ -159,12 +139,12 @@ static int php_is_file_ok(const cwd_state *state)
|
||||
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);
|
||||
}
|
||||
@@ -189,20 +169,7 @@ CWD_API void virtual_cwd_startup(void)
|
||||
char cwd[MAXPATHLEN];
|
||||
char *result;
|
||||
|
||||
#ifdef NETWARE
|
||||
result = getcwdpath(cwd, NULL, 1);
|
||||
if(result)
|
||||
{
|
||||
char *c=cwd;
|
||||
while(c = strchr(c, '\\'))
|
||||
{
|
||||
*c='/';
|
||||
++c;
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
#endif
|
||||
if (!result) {
|
||||
cwd[0] = '\0';
|
||||
}
|
||||
@@ -210,12 +177,12 @@ 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(NETWARE)) && defined(ZTS)
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
cwd_mutex = tsrm_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
@@ -223,18 +190,19 @@ 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(NETWARE)) && defined(ZTS)
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
tsrm_mutex_free(cwd_mutex);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
@@ -267,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;
|
||||
@@ -289,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,28 +270,16 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
unsigned char is_absolute = 0;
|
||||
#ifndef TSRM_WIN32
|
||||
char resolved_path[MAXPATHLEN];
|
||||
#else
|
||||
char *new_path;
|
||||
#endif
|
||||
|
||||
if (path_length == 0)
|
||||
return (0);
|
||||
if (path_length >= MAXPATHLEN)
|
||||
return (1);
|
||||
|
||||
#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) {
|
||||
if (realpath(path, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
} else {
|
||||
/* disable for now
|
||||
return 1; */
|
||||
}
|
||||
#ifndef TSRM_WIN32
|
||||
if (IS_ABSOLUTE_PATH(path, path_length)) {
|
||||
if (realpath(path, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
}
|
||||
} else { /* Concat current directory with relative path and then run realpath() on it */
|
||||
char *tmp;
|
||||
@@ -339,45 +295,12 @@ 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 (strlen(tmp) >= MAXPATHLEN) {
|
||||
free(tmp);
|
||||
return 1;
|
||||
}
|
||||
if (use_realpath) {
|
||||
if (realpath(tmp, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
} else {
|
||||
/* disable for now
|
||||
free(tmp);
|
||||
return 1; */
|
||||
}
|
||||
if (realpath(tmp, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
#if defined(TSRM_WIN32)
|
||||
{
|
||||
char *dummy = NULL;
|
||||
int new_path_length;
|
||||
|
||||
new_path_length = GetLongPathName(path, dummy, 0) + 1;
|
||||
if (new_path_length == 0) {
|
||||
return 1;
|
||||
}
|
||||
new_path = (char *) malloc(new_path_length);
|
||||
if (!new_path) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (GetLongPathName(path, new_path, new_path_length) != 0) {
|
||||
path = new_path;
|
||||
path_length = new_path_length;
|
||||
} else {
|
||||
free(new_path);
|
||||
new_path = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
free_path = path_copy = tsrm_strndup(path, path_length);
|
||||
|
||||
@@ -387,10 +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_SLASH(path_copy[0])) {
|
||||
} else if(IS_SLASH(path_copy[0])) {
|
||||
copy_amount = 2;
|
||||
#endif
|
||||
}
|
||||
@@ -410,75 +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)
|
||||
/*
|
||||
Below code keeps appending to state->cwd a File system seperator
|
||||
cases where this appending should not happen is given below,
|
||||
a) sys: should just be left as it is
|
||||
b) sys:system should just be left as it is,
|
||||
Colon is allowed only in the first token as volume names alone can have the : in their names.
|
||||
Files and Directories cannot have : in their names
|
||||
So the check goes like this,
|
||||
For second token and above simply append the DEFAULT_SLASH to the state->cwd.
|
||||
For first token check for the existence of :
|
||||
if it exists don't append the DEFAULT_SLASH to the state->cwd.
|
||||
*/
|
||||
if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
|
||||
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)) {
|
||||
@@ -493,11 +386,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
|
||||
}
|
||||
|
||||
free(old_state);
|
||||
#ifdef TSRM_WIN32
|
||||
if (new_path) {
|
||||
free(new_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
free(free_path);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
|
||||
@@ -505,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;
|
||||
@@ -528,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);
|
||||
@@ -537,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);
|
||||
|
||||
@@ -601,34 +485,15 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC)
|
||||
return f;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
#if defined(TSRM_WIN32)
|
||||
ret = tsrm_win32_access(new_state.cwd, mode);
|
||||
#else
|
||||
ret = access(new_state.cwd, mode);
|
||||
#endif
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
@@ -637,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);
|
||||
|
||||
@@ -651,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);
|
||||
|
||||
@@ -667,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);
|
||||
@@ -691,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);
|
||||
|
||||
@@ -705,35 +574,15 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -742,28 +591,32 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
}
|
||||
|
||||
#ifndef TSRM_WIN32
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
|
||||
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, 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);
|
||||
|
||||
@@ -771,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);
|
||||
@@ -788,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);
|
||||
|
||||
@@ -806,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);
|
||||
|
||||
@@ -820,67 +676,19 @@ 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;
|
||||
int dir_length, extra = 0;
|
||||
char *command_line;
|
||||
char *ptr, *dir;
|
||||
char *ptr;
|
||||
FILE *retval;
|
||||
CWDLS_FETCH();
|
||||
|
||||
command_length = strlen(command);
|
||||
|
||||
dir_length = CWDG(cwd).cwd_length;
|
||||
dir = CWDG(cwd).cwd;
|
||||
while (dir_length > 0) {
|
||||
if (*dir == '\'') extra+=3;
|
||||
dir++;
|
||||
dir_length--;
|
||||
}
|
||||
dir_length = CWDG(cwd).cwd_length;
|
||||
dir = CWDG(cwd).cwd;
|
||||
|
||||
ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length +extra+1+1);
|
||||
ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1);
|
||||
if (!command_line) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -890,21 +698,8 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
|
||||
if (CWDG(cwd).cwd_length == 0) {
|
||||
*ptr++ = DEFAULT_SLASH;
|
||||
} else {
|
||||
*ptr++ = '\'';
|
||||
while (dir_length > 0) {
|
||||
switch (*dir) {
|
||||
case '\'':
|
||||
*ptr++ = '\'';
|
||||
*ptr++ = '\\';
|
||||
*ptr++ = '\'';
|
||||
/* fall-through */
|
||||
default:
|
||||
*ptr++ = *dir;
|
||||
}
|
||||
dir++;
|
||||
dir_length--;
|
||||
}
|
||||
*ptr++ = '\'';
|
||||
memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length);
|
||||
ptr += CWDG(cwd).cwd_length;
|
||||
}
|
||||
|
||||
*ptr++ = ' ';
|
||||
@@ -912,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
|
||||
|
||||
|
||||
|
||||
+89
-168
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP version 4.0 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
| Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| 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 through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.txt. |
|
||||
| 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. |
|
||||
@@ -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,41 +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 is 2 under Win32 because by chance both regular absolute paths
|
||||
in the file system and UNC paths need copying of two characters */
|
||||
#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 IS_SLASH_P(c) IS_SLASH(*(c))
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
|
||||
(len >= 2 && isalpha(path[0]) && path[1] == ':')
|
||||
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
@@ -83,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
|
||||
@@ -128,80 +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);
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *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
|
||||
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);
|
||||
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
|
||||
#if defined(TSRM_WIN32)
|
||||
/* these are not defined in win32 headers */
|
||||
#ifndef W_OK
|
||||
#define W_OK 0x02
|
||||
#endif
|
||||
#ifndef R_OK
|
||||
#define R_OK 0x04
|
||||
#endif
|
||||
#ifndef X_OK
|
||||
#define X_OK 0x01
|
||||
#endif
|
||||
#ifndef F_OK
|
||||
#define F_OK 0x00
|
||||
#endif
|
||||
#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
|
||||
@@ -211,75 +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)
|
||||
#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 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 V_UTIME(path,time) virtual_utime(path,time)
|
||||
#endif
|
||||
#define V_CHMOD(path,mode) virtual_chmod(path,mode)
|
||||
#ifndef TSRM_WIN32
|
||||
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#define V_CHOWN(path,owner,group) virtual_chown(path,owner,group)
|
||||
#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)
|
||||
|
||||
#else
|
||||
|
||||
#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) virtual_utime(path, time TSRMLS_CC)
|
||||
#define V_UTIME(path,time) 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)
|
||||
#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)
|
||||
#if defined(TSRM_WIN32)
|
||||
#define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode)
|
||||
#else
|
||||
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#if HAVE_UTIME
|
||||
#define VCWD_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
|
||||
|
||||
@@ -1,388 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.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>
|
||||
|
||||
#define TSRM_INCLUDE_FULL_WINDOWS_HEADERS
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
|
||||
{
|
||||
SHFILEINFO sfi;
|
||||
|
||||
if (mode == 1 /*X_OK*/) {
|
||||
return access(pathname, 0) == 0 &&
|
||||
SHGetFileInfo(pathname, 0, &sfi, sizeof(SHFILEINFO), SHGFI_EXETYPE) != 0 ? 0 : -1;
|
||||
} else {
|
||||
return access(pathname, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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, ©, 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
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_0.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 tsrm_win32_access(const char *pathname, int mode);
|
||||
|
||||
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
|
||||
-17629
File diff suppressed because it is too large.
Load diff
+110
-50
@@ -1,56 +1,116 @@
|
||||
--------------------------------------------------------------------
|
||||
The Zend Engine License, Version 2.00
|
||||
Copyright (c) 1999-2003 Zend Technologies Ltd. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
The Zend License, version 0.92
|
||||
Copyright (C) 1999-2000 Zend Technologies Ltd.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
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.
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
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.
|
||||
|
||||
3. The names "Zend" and "Zend Engine" must not be used to endorse
|
||||
or promote products derived from this software without prior
|
||||
permission from Zend Technologies Ltd. For written permission,
|
||||
please contact license@zend.com.
|
||||
|
||||
4. Zend Technologies Ltd. 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
|
||||
published by Zend Technologies Ltd. No one other than Zend
|
||||
Technologies Ltd. has the right to modify the terms applicable
|
||||
to covered code created under this License.
|
||||
For more information about Zend please visit http://www.zend.com/
|
||||
For license related questions please mail license@zend.com
|
||||
|
||||
5. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes the Zend Engine, freely available at
|
||||
http://www.zend.com"
|
||||
===========================================================================
|
||||
|
||||
6. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"The Zend Engine is freely available at http://www.zend.com"
|
||||
THE Q PUBLIC LICENSE
|
||||
version 1.0
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ZEND
|
||||
TECHNOLOGIES LTD. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
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.
|
||||
|
||||
|
||||
===========================================================================
|
||||
+20
-33
@@ -1,54 +1,41 @@
|
||||
## Process this file with automake to produce Makefile.in -*- makefile -*-
|
||||
|
||||
#CLEANFILES = zend_language_parser.c zend_language_parser.h zend_language_scanner.c zend_language_parser.output zend_ini_parser.c zend_ini_parser.h zend_ini_scanner.c zend_ini_parser.output
|
||||
#CLEANFILES = zend-parser.c zend-parser.h zend-scanner.c zend-parser.output
|
||||
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
noinst_LTLIBRARIES=libZend.la
|
||||
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_language_parser.y zend_language_scanner.l \
|
||||
zend_ini_parser.y zend_ini_scanner.l \
|
||||
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 \
|
||||
zend_ini.c zend_qsort.c zend_objects.c zend_object_handlers.c \
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c zend_mm.c \
|
||||
zend_default_classes.c zend_reflection_api.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_multibyte.c
|
||||
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c
|
||||
|
||||
libZend_la_LDFLAGS =
|
||||
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
|
||||
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_language_parser.h
|
||||
$(libZend_la_OBJECTS) zend-scanner.lo zend-scanner-cc.lo: zend-parser.h
|
||||
|
||||
zend_ini_scanner.lo: zend_ini_parser.h
|
||||
zend-scanner.c: $(srcdir)/zend-scanner.l
|
||||
$(LEX) -Pzend -o$@ -i $(srcdir)/zend-scanner.l
|
||||
|
||||
# Language parser/scanner rules
|
||||
zend-scanner-cc.cc: $(srcdir)/zend-scanner.l
|
||||
$(LEX) -+ -B -i -S$(srcdir)/flex.skl -Pzend -o$@ $(srcdir)/zend-scanner.l
|
||||
|
||||
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
|
||||
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
|
||||
|
||||
zend_language_parser.h: zend_language_parser.c
|
||||
zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o zend_language_parser.c
|
||||
|
||||
# INI parser/scanner rules
|
||||
|
||||
zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o zend_ini_parser.c
|
||||
|
||||
zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
|
||||
|
||||
zend_ini_parser.h: zend_ini_parser.c
|
||||
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) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(INLINE_CFLAGS) -c $(srcdir)/zend_execute.c
|
||||
|
||||
$(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(INLINE_CFLAGS) -c $(srcdir)/zend_execute.c
|
||||
@@ -1,195 +0,0 @@
|
||||
Creating an object
|
||||
------------------
|
||||
|
||||
Object can be created in the following ways:
|
||||
|
||||
1. As a result of a function call. E.g.:
|
||||
|
||||
$foo = create_new_foo("parameter");
|
||||
$foo->run();
|
||||
|
||||
The function should create a new zval, create new object and get the
|
||||
handle for it, set handle and handler table as needed. Note that the
|
||||
handle is the only ID of the object, so it should be enough to
|
||||
identify it.
|
||||
|
||||
2. Overriding create_object handler for class. E.g.:
|
||||
|
||||
$foo = new Java("some.Class.here", "parameter");
|
||||
$foo->run();
|
||||
|
||||
The create_object handler function should create a new zval, create
|
||||
new object and get the handle for it, set handle and handler table as
|
||||
needed, and also provide constructor method that would handle
|
||||
constructor call. The get_constructor handler table entry should be
|
||||
used for that. Do not rely class entry's constructor, unless you refer
|
||||
to it from get_constructor handler.
|
||||
|
||||
Object maintenance
|
||||
------------------
|
||||
|
||||
The handlers add_ref and del_ref are called when a new zval referring
|
||||
to the object is created. This does not create a new object - both
|
||||
zvals still refer to the same object.
|
||||
|
||||
clone_obj handler should create a new object, identical to an old one,
|
||||
but being a separate entity.
|
||||
|
||||
delete_obj should destroy an object, all references to it become
|
||||
invalid.
|
||||
|
||||
Object access - read
|
||||
--------------------
|
||||
|
||||
read_property is used to read object's property. This value is not
|
||||
meant to be changed. The handler returns zval * with the value.
|
||||
|
||||
Object access - write
|
||||
---------------------
|
||||
|
||||
write_property is used to directly write object's property by
|
||||
name. This handler is used to assign property variables or to change them
|
||||
in operations like += or ++ (unless get_property_zval_ptr is also set).
|
||||
|
||||
get_property_zval_ptr is used to obtain pointer to modifiable zval for
|
||||
operations like += or ++. This should be used only if your object model
|
||||
stores properties as real zval's that can be modified from outside.
|
||||
Otherwise this handler should be NULL and the engine will use
|
||||
read_property and write_property instead.
|
||||
|
||||
get_property_ptr is used to obtain zval ** for future writing to
|
||||
it. If your object properties are stored as zval*, return real place
|
||||
where the property is stored. If the aren't, the best way is to create
|
||||
proxy object and handle it via get and set methods (see below).
|
||||
This method is meant to be used for send-by-reference and assign-by-reference
|
||||
use of object properties. If you don;t want to implement property
|
||||
referencing for your objects, you can set this handler to NULL.
|
||||
|
||||
get and set handlers are used when engine needs to access the object
|
||||
as a value. E.g., in the following situation:
|
||||
|
||||
$foo =& $obj->bar;
|
||||
$foo = 1;
|
||||
|
||||
if $foo is an object (e.g., proxy object from get_property_ptr) it
|
||||
would be accessed using write handler.
|
||||
|
||||
Object access - method call
|
||||
---------------------------
|
||||
|
||||
get_method handler is used to find method description by name. It
|
||||
should set right type, function name and parameter mask for the
|
||||
method. If the type is ZEND_OVERLOADED_FUNCTION, the method would be
|
||||
called via call_method handler, otherwise it would be called with
|
||||
standard Zend means.
|
||||
|
||||
get_constructor performs the same function as get_method, but for the
|
||||
object constructor.
|
||||
|
||||
call_method handler is used to perform method call. Parameters are
|
||||
passed like to any other Zend internal function.
|
||||
|
||||
Object - comparison
|
||||
-------------------
|
||||
|
||||
Objects can be compared via compare_objects handler. This is used with
|
||||
== operation, === compares objects by handles, i.e., return true if
|
||||
and only if it's really the same object. Note that objects from
|
||||
different object types (i.e., having different handlers) can not be
|
||||
compared.
|
||||
|
||||
Objects - reflection
|
||||
--------------------
|
||||
|
||||
get_class_name is used to retrieve class name of the object.
|
||||
get_class_entry returns class entry (zend_class_entry) for the object,
|
||||
in case there exists PHP class for it.
|
||||
No other reflection functions are currently implemented.
|
||||
|
||||
Objects - data structures and handlers
|
||||
---------------------------------------
|
||||
|
||||
The object is represented by the following structure:
|
||||
|
||||
struct _zend_object_value {
|
||||
zend_object_handle handle;
|
||||
zend_object_handlers *handlers;
|
||||
};
|
||||
|
||||
handle is an ID of the object among the objects of the same type (not
|
||||
class!). The type of the object and how it behaves is determined by
|
||||
the handler table.
|
||||
|
||||
typedef struct _zend_object_handlers {
|
||||
zend_object_add_ref_t add_ref;
|
||||
zend_object_del_ref_t del_ref;
|
||||
zend_object_delete_obj_t delete_obj;
|
||||
zend_object_clone_obj_t clone_obj;
|
||||
zend_object_read_property_t read_property;
|
||||
zend_object_write_property_t write_property;
|
||||
zend_object_get_property_ptr_t get_property_ptr;
|
||||
zend_object_get_property_zval_ptr_t get_property_zval_ptr;
|
||||
zend_object_get_t get;
|
||||
zend_object_set_t set;
|
||||
zend_object_has_property_t has_property;
|
||||
zend_object_unset_property_t unset_property;
|
||||
zend_object_get_properties_t get_properties;
|
||||
zend_object_get_method_t get_method;
|
||||
zend_object_call_method_t call_method;
|
||||
zend_object_get_constructor_t get_constructor;
|
||||
zend_object_get_class_entry_t get_class_entry;
|
||||
zend_object_get_class_name_t get_class_name;
|
||||
zend_object_compare_t compare_objects;
|
||||
} zend_object_handlers;
|
||||
|
||||
See zend_object_handlers.h for prototypes. All objects are passed as zval's.
|
||||
|
||||
Handlers explained:
|
||||
|
||||
add_ref - called when a copy of the object handle is created.
|
||||
|
||||
del_ref - called when a copy of the object handle is destroyed.
|
||||
|
||||
delete_obj - called when an object needs to be destroyed.
|
||||
|
||||
clone_obj - called when a new object identical to an old one should be
|
||||
created (unlike Zend Engine 1, this never happens unless explicitly
|
||||
asked for).
|
||||
|
||||
read_property - returns zval *, containing the value of the
|
||||
property. Is used when value of the property should be retrieved for
|
||||
reading.
|
||||
|
||||
write_property - assigns value to certain property of the object.
|
||||
|
||||
get_property_zval_ptr - retrieves zval** for being directly modified by
|
||||
the engine. If your properties are not zval's, don't define it.
|
||||
|
||||
get_property_ptr - retrieves zval** for the property of the value, to
|
||||
be used for read and write. If object properties are not zval's
|
||||
natively, this method should create and return proxy object for use
|
||||
with get and set methods.
|
||||
|
||||
get - retrieves zval* for object contents. To be used mainly with
|
||||
proxy objects from get_property_ptr, but also may be used for
|
||||
convert_to_* functions.
|
||||
|
||||
set - sets value for object contents. To be used mainly with
|
||||
proxy objects from get_property_ptr.
|
||||
|
||||
has_property - checks if the object has certain property set.
|
||||
|
||||
unset_property - removes value for the property of the object
|
||||
|
||||
get_method - retrieves description of the method
|
||||
|
||||
call_method - calls the method (parameters should be put on stack like
|
||||
for any other PHP internal function).
|
||||
|
||||
get_constructor - get description for the object constructor method
|
||||
|
||||
get_class_entry - should return the class entry for the object
|
||||
|
||||
get_class_name - get the name of the class the object belongs to
|
||||
|
||||
compare_objects - compares if two objects are equal
|
||||
@@ -1,136 +0,0 @@
|
||||
Revamped object model using object handles
|
||||
===========================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
In the Zend Engine 1.0 (and its predecessor the PHP 3 scripting
|
||||
engine) the object model's design is that instantiated objects are
|
||||
language values. This means that when programmers are performing
|
||||
operations, such variable assignment and passing parameters to
|
||||
functions, objects are handled very similarly to the way other
|
||||
primitive types are handled such as integers and strings.
|
||||
Semantically this means that the whole object is being copied. The
|
||||
approach Java takes is different where one refers to objects by handle
|
||||
and not by value (one can think of a handle as an objects' ID).
|
||||
|
||||
Need
|
||||
----
|
||||
|
||||
Unfortunately, the approach taken up to now has severely limited the
|
||||
Zend Engine's object oriented model, both feature and simplicity
|
||||
wise. One of the main problems with the former approach is that object
|
||||
instantiation and duplication is very hard to control, a problem which
|
||||
can not only lead to inefficient development but also often to strange
|
||||
run-time behavior. Changing the object model to a handle oriented
|
||||
model will allow the addressing of many needs such as destructors,
|
||||
de-referencing method return values, tight control of object
|
||||
duplication and more.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The proposed object model is very much influenced by the Java
|
||||
model. In general, when you create a new object you will be getting a
|
||||
handle to the object instead of the object itself. When this handle is
|
||||
sent to functions, assigned and copied it is only the handle which is
|
||||
copied/sent/assigned. The object itself is never copied nor
|
||||
duplicated. This results in all handles of this object to always point
|
||||
at the same object making it a very consistent solution and saving
|
||||
unnecessary duplication and confusing behavior.
|
||||
|
||||
Functionality
|
||||
-------------
|
||||
|
||||
After this change the basic use of objects will be almost identical to
|
||||
previous versions of the scripting engine. However, you won't bump
|
||||
into awkward and confusing copying & destructing of objects. In order
|
||||
to create and use a new object instance you will do the following:
|
||||
$object = new MyClass(); $object->method();
|
||||
|
||||
The previous code will assign $object the handle of a new instance of
|
||||
the class MyClass and call one of its methods.
|
||||
|
||||
|
||||
Consider the following code:
|
||||
|
||||
1 class MyClass
|
||||
2 {
|
||||
3 function setMember($value)
|
||||
4 {
|
||||
5 $this->member = $value;
|
||||
6 }
|
||||
7
|
||||
8 function getMember()
|
||||
9 {
|
||||
10 return $this->member;
|
||||
11 }
|
||||
12 }
|
||||
13
|
||||
14 function foo($obj)
|
||||
15 {
|
||||
16 $obj->setMember("foo");
|
||||
17 }
|
||||
18
|
||||
19 $object = new MyClass();
|
||||
20 $object->setMember("bar");
|
||||
21 foo($object);
|
||||
22 print $object->getMember();
|
||||
|
||||
Without the new Java-like handles, at line 20 the objects' data member
|
||||
member is set to the string value of "bar". Because of the internal
|
||||
representation of objects in the Zend Engine 1.0, the object is marked
|
||||
as a reference, and when it is sent by value to the function foo, it
|
||||
is duplicated (!). Therefore, the call to foo() on line 21 will
|
||||
result in the $obj->setMember("foo") call being called on a duplicate
|
||||
of $object. Line 22 will then result in "bar" being printed.
|
||||
|
||||
This is how the scripting engine has worked until today. Most
|
||||
developers are probably unaware of the fact that they aren't always
|
||||
talking to the same object but often duplicates; others may have
|
||||
realized this can usually be solved by always passing objects by
|
||||
reference (unless a replica is actually desired, which is uncommon).
|
||||
|
||||
The new object model will allow for a much more intuitive
|
||||
implementation of the code. On line 21, the object's handle (ID) is
|
||||
passed to foo() by value. Inside foo(), the object is fetched
|
||||
according to this handle and, therefore, the setMember() method is
|
||||
called on the originally instantiated object and not a copy. Line 22
|
||||
will therefore result in "foo" being printed. This approach gives
|
||||
developers tighter control of when objects are created and duplicated.
|
||||
An additional not-as-important benefit is that the object handle will
|
||||
be passed to foo() by value, which most probably will also save
|
||||
unnecessary duplication of the value containing the ID itself and thus
|
||||
additionally improving run-time performance.
|
||||
|
||||
This was just a simple description of why the new object model solves
|
||||
awkward behavior and makes object handling much easier, intuitive and
|
||||
efficient. The importance of this change goes far beyond what is
|
||||
mentioned in this section as you will see in further sections which
|
||||
describe new features with a majority of them being based on this
|
||||
change.
|
||||
|
||||
Compatibility Notes
|
||||
--------------------
|
||||
|
||||
Many PHP programmers aren't even aware of the copying quirks of the
|
||||
current object model and, therefore, there is a relatively good chance
|
||||
that the amount of PHP applications that will work out of the box or
|
||||
after a very small amount of modifications would be high.
|
||||
|
||||
To simplify migration, version 2.0 will support an optional
|
||||
'auto-clone' feature, which will perform a cloning of the object
|
||||
whenever it would have been copied in version 1.0. Optionally, it
|
||||
will also be possible to request that the engine will emit an E_NOTICE
|
||||
message whenever such an automatic clone occurs, in order to allow
|
||||
developers to gradually migrate to the version 2.0-style behavior
|
||||
(without automatic clones).
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The new object model is not dependent on other features. Many of the
|
||||
other Zend Engine 2.0 features, such as the $foo->bar()->barbara()
|
||||
syntax, destructors and others completely rely on this new object
|
||||
model.
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
Title: Zend 2.0 Namespaces
|
||||
Version: $Revision$
|
||||
Status: declined
|
||||
Maintainer: Stig S. Bakken <ssb@php.net>
|
||||
Created: 2001-09-08
|
||||
Modified: 2001-09-08
|
||||
|
||||
|
||||
1. Background/Need
|
||||
==================
|
||||
|
||||
PHP and Zend 1.0 have come to a point where a lot of reusable code is
|
||||
being written; from simple functions and classes to entire application
|
||||
frameworks. It is becoming increasingly difficult to avoid symbol
|
||||
name collisions with the current scoping methods.
|
||||
|
||||
The symbol scopes available in Zend 1.0 are the global scope, the
|
||||
class scope and the function scope. All scopes but classes may
|
||||
contain variables, only the class and global scopes may contain
|
||||
functions, while only the global scope may contain constants and
|
||||
classes. This means that all of Zend 1.0's scoping methods are
|
||||
inherently limited for solving symbol name collision problems.
|
||||
|
||||
|
||||
2. Overview
|
||||
===========
|
||||
|
||||
Namespaces in Zend 2.0 provide a way to manage the symbol collision
|
||||
problem by making it possible to define multiple symbol tables able to
|
||||
contain all types of symbols. Zend will get the notion of a current
|
||||
namespace, defaulting to the current global one. The current name
|
||||
space may be changed on a file-by-file basis. Symbols in other name
|
||||
spaces than the current one may be referenced using a new namespace
|
||||
operator. It will be possible to "import" symbols from one namespace
|
||||
into another.
|
||||
|
||||
|
||||
3. Functionality
|
||||
================
|
||||
|
||||
3.1. Namespace Syntax
|
||||
=====================
|
||||
|
||||
The namespace operator ":" is used to refer to symbols in other
|
||||
namespaces than the current one:
|
||||
|
||||
Class: Namespace:class
|
||||
Function: Namespace:function
|
||||
Static method: Namespace:class::method
|
||||
Variable: $Namespace:variable
|
||||
Constant: Namespace:CONSTANT
|
||||
Class variable: $Namespace:class::variable
|
||||
|
||||
To refer to symbols in the global namespace, symbols are prefixed with
|
||||
only the namespace operator:
|
||||
|
||||
Class: :class
|
||||
Function: :function
|
||||
Static method: :class::method
|
||||
Variable: $:variable
|
||||
Constant: :CONSTANT
|
||||
Class variable: $:class::variable
|
||||
|
||||
Note: $:variable will effectively be just another syntax for
|
||||
$GLOBALS['variable'].
|
||||
|
||||
A namespace may have a name containing a ":", it is always the last
|
||||
":" character in the symbol qualifier that is the actual namespace
|
||||
operator:
|
||||
|
||||
Class: Name:Space:class
|
||||
Function: Name:Space:function
|
||||
Static method: Name:Space:class::method
|
||||
Variable: $Name:Space:variable
|
||||
Constant: Name:Space:CONSTANT
|
||||
Class variable: $Name:Space:class::variable
|
||||
|
||||
(Here, the ":" between "Name" and "Space" is part of the name, it is
|
||||
the one after "Space" that is the namespace operator.)
|
||||
|
||||
|
||||
3.2. Defining Namespaces
|
||||
========================
|
||||
|
||||
Individual files may define a namespace that will apply to the entire
|
||||
file. If no "namespace" operator occurs in the file, it will be in
|
||||
the global namespace:
|
||||
|
||||
1 namespace HTML;
|
||||
2
|
||||
3 class Form {
|
||||
4 function Form() {
|
||||
5 // constructor
|
||||
6 }
|
||||
7 // ...
|
||||
8 }
|
||||
|
||||
Or with the "nested" name syntax:
|
||||
|
||||
1 namespace HTML:Form;
|
||||
2
|
||||
3 class Image {
|
||||
4 var $src;
|
||||
5 function Image($src) {
|
||||
6 $this->src = $src;
|
||||
7 }
|
||||
8 // ...
|
||||
9 }
|
||||
|
||||
Code executed within the "HTML" namespace may refer to the Form class
|
||||
as just "Form". Code executed from within other namespaces has to
|
||||
refer to it as "HTML:Form". The "namespace" statement must occur
|
||||
before any other statements in the file.
|
||||
|
||||
# [ssb 2001-09-08]:
|
||||
# Should it be possible to "add" symbols to a namespace by including a
|
||||
# second file with the same namespace statement?
|
||||
|
||||
|
||||
3.3. Importing Symbols
|
||||
======================
|
||||
|
||||
It is possible to import symbols from another namespace into the
|
||||
current one with the "import" statement:
|
||||
|
||||
import * from HTML; // all symbols
|
||||
|
||||
import Form from HTML; // single symbols
|
||||
|
||||
import Form,Table from HTML; // multiple symbols
|
||||
|
||||
There is a potential for name clashes between symols of different
|
||||
types that have the same qualifier syntax. These are resolved in this
|
||||
order: class, function, constant.
|
||||
|
||||
Optionally, the symbol type may be explicitly given to import (as
|
||||
"class", "function", "variable" or "constant"):
|
||||
|
||||
import class Form from HTML;
|
||||
|
||||
And finally, you may import all symbols of a given type:
|
||||
|
||||
import constant * from HTML:Table;
|
||||
|
||||
The namespace with its symbols must already be defined before using
|
||||
"import".
|
||||
|
||||
|
||||
4. Compatibility Notes
|
||||
======================
|
||||
|
||||
Old code that does not take advantage of namespaces will run without
|
||||
modifications.
|
||||
|
||||
|
||||
5. Dependencies
|
||||
===============
|
||||
|
||||
The class variable syntax depends on this class variables being
|
||||
implemented in the new ZE2 object model.
|
||||
|
||||
|
||||
6. Acknowledgements
|
||||
===================
|
||||
|
||||
Andi Gutmans <andi@zend.com> and Zeev Suraski <zeev@zend.com> for
|
||||
initial ZE2 namespaces proposal
|
||||
|
||||
Dean Hall <php@apt7.com> for the initial symbol qualification syntax
|
||||
@@ -1,72 +0,0 @@
|
||||
Title: Loose type requirements for functions
|
||||
Version: $Revision$
|
||||
Status: draft
|
||||
Maintainer: Brian Moon <brianm@dealnews.com>
|
||||
Created: 2001-09-17
|
||||
Modified: 2001-09-17
|
||||
|
||||
|
||||
1. Background/Need
|
||||
==================
|
||||
|
||||
Many internal function of PHP will reject parameters because of their
|
||||
type (the array and variable function come to mind). For userland
|
||||
this is not an easy task as there is no uniform way to do it. An
|
||||
addition to the engine for requiring loose types would allow
|
||||
delevopers to know that the data passed to their functions is of the
|
||||
correct type and reduce the need for duplicating the same code in
|
||||
every function to check for the type of data.
|
||||
|
||||
|
||||
2. Overview
|
||||
===========
|
||||
|
||||
Loose typing mostly means evaluating the contents of the variable and
|
||||
not the type of the variable itself. The requirements for this would
|
||||
and should work much like several of the is_* functions do now.
|
||||
|
||||
The typing of parameters would be optional and those not typed would
|
||||
simply continue to be treated as they are now.
|
||||
|
||||
3. Functionality
|
||||
================
|
||||
|
||||
3.1. Allowed Types
|
||||
==================
|
||||
|
||||
Only loose types should be needed to ensure the data is usable by the
|
||||
function. Duplicating the functionallity of is_scalar, is_resource,
|
||||
is_array and is_object should give developers all the information they
|
||||
need to use a variable correctly.
|
||||
|
||||
3.2. Syntax
|
||||
===========
|
||||
|
||||
The current function syntax should be expanded to allow typing of
|
||||
variables inline in a C style.
|
||||
|
||||
function foo ($var){
|
||||
}
|
||||
|
||||
could be changed to require an array such as:
|
||||
|
||||
function foo (array $var){
|
||||
}
|
||||
|
||||
3.3. Errors
|
||||
===========
|
||||
|
||||
Mis-matches in type should be reported as fatal errors and should halt
|
||||
the execution of a script as that function can not be run and code
|
||||
following could not reliably run.
|
||||
|
||||
|
||||
4. Compatibility Notes
|
||||
======================
|
||||
|
||||
Old code that does not take advantage of this will run without
|
||||
modifications.
|
||||
|
||||
|
||||
|
||||
|
||||
+111
-1166
File diff suppressed because it is too large.
Load diff
+53
-227
@@ -107,6 +107,14 @@ LIB32=link.exe -lib
|
||||
# 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
|
||||
@@ -131,14 +139,6 @@ SOURCE=.\zend_constants.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_default_classes.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
|
||||
@@ -151,6 +151,10 @@ 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
|
||||
@@ -163,30 +167,6 @@ SOURCE=.\zend_indent.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -195,22 +175,6 @@ SOURCE=.\zend_llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects_API.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_opcode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -223,14 +187,6 @@ SOURCE=.\zend_ptr_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_qsort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_sprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -239,18 +195,6 @@ SOURCE=.\zend_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -263,6 +207,18 @@ 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
|
||||
@@ -291,14 +247,6 @@ SOURCE=.\zend_constants.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_default_classes.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
|
||||
@@ -307,10 +255,6 @@ 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
|
||||
@@ -323,10 +267,6 @@ 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
|
||||
@@ -339,34 +279,6 @@ SOURCE=.\zend_indent.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -375,26 +287,6 @@ SOURCE=.\zend_llist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_modules.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects_API.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_operators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -403,30 +295,10 @@ SOURCE=.\zend_ptr_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_qsort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.h
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -435,48 +307,23 @@ SOURCE=.\zend_variables.h
|
||||
# PROP Default_Filter "y"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.y
|
||||
|
||||
!IF "$(CFG)" == "Zend - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=.\zend_ini_parser.y
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
|
||||
|
||||
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.y"
|
||||
SOURCE=".\zend-parser.y"
|
||||
|
||||
!IF "$(CFG)" == "Zend - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
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_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -484,15 +331,17 @@ BuildCmds= \
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
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_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -500,15 +349,17 @@ BuildCmds= \
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
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_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -521,60 +372,35 @@ BuildCmds= \
|
||||
# PROP Default_Filter "l"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\flex.skl
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.l
|
||||
|
||||
!IF "$(CFG)" == "Zend - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=.\zend_ini_scanner.l
|
||||
|
||||
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "Zend - Win32 Release_inline"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.l"
|
||||
SOURCE=".\zend-scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "Zend - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend_language_scanner.l"
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -i -Pzend -ozend_language_scanner.c zend_language_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_language_scanner.l"
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -i -Pzend -ozend_language_scanner.c zend_language_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_language_scanner.l"
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -i -Pzend -ozend_language_scanner.c zend_language_scanner.l
|
||||
"zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -i -Pzend -ozend-scanner.c zend-scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
||||
+78
-155
@@ -1,52 +1,25 @@
|
||||
dnl
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl This file contains Zend specific autoconf functions.
|
||||
dnl
|
||||
|
||||
AC_DEFUN([LIBZEND_BISON_CHECK],[
|
||||
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| grep 'GNU Bison' | cut -d ' ' -f 4 | sed -e 's/\./ /' | tr -d 'a-z'`
|
||||
if test "${1}" = "1" -a "${2}" -lt "28"; then
|
||||
AC_MSG_WARN(You will need bison 1.28 if you want to regenerate the Zend parser (found ${1}.${2}).)
|
||||
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_CHECK_INT_TYPE],[
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_TRY_COMPILE([
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif],
|
||||
[if (($1 *) 0)
|
||||
return 0;
|
||||
if (sizeof ($1))
|
||||
return 0;
|
||||
],[
|
||||
AC_DEFINE_UNQUOTED([HAVE_]translit($1,a-z_-,A-Z__), 1,[Define if $1 type is present. ])
|
||||
AC_MSG_RESULT(yes)
|
||||
], AC_MSG_RESULT(no)
|
||||
)dnl
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
|
||||
AC_DEFUN(LIBZEND_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_YACC])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_PROG_CC_C_O])
|
||||
AC_REQUIRE([AC_PROG_LEX])
|
||||
AC_REQUIRE([AM_PROG_LEX])
|
||||
AC_REQUIRE([AC_HEADER_STDC])
|
||||
|
||||
LIBZEND_BISON_CHECK
|
||||
@@ -64,69 +37,50 @@ if test "$ac_cv_prog_gcc" = "yes" -a "`uname -s`" = "Rhapsody"; then
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(
|
||||
inttypes.h \
|
||||
stdint.h \
|
||||
limits.h \
|
||||
malloc.h \
|
||||
string.h \
|
||||
unistd.h \
|
||||
stdarg.h \
|
||||
sys/types.h \
|
||||
sys/time.h \
|
||||
signal.h \
|
||||
unix.h \
|
||||
stdlib.h \
|
||||
mach-o/dyld.h \
|
||||
dlfcn.h)
|
||||
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SIGNAL
|
||||
|
||||
AC_DEFUN([LIBZEND_LIBDL_CHECKS],[
|
||||
AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS"])
|
||||
AC_CHECK_FUNC(dlopen,[AC_DEFINE(HAVE_LIBDL, 1,[ ])])
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
|
||||
dnl
|
||||
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
|
||||
_LT_AC_TRY_DLOPEN_SELF([
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [])
|
||||
])
|
||||
|
||||
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 Check if int32_t and uint32_t are defined
|
||||
LIBZEND_CHECK_INT_TYPE(int32_t)
|
||||
LIBZEND_CHECK_INT_TYPE(uint32_t)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_MEMCMP
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(memcpy strdup getpid kill strtod strtol finite fpclass)
|
||||
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_DEFUN(LIBZEND_ENABLE_DEBUG,[
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Compile with debugging symbols],[
|
||||
[ --enable-debug Compile with debugging symbols],[
|
||||
ZEND_DEBUG=$enableval
|
||||
],[
|
||||
ZEND_DEBUG=no
|
||||
@@ -134,30 +88,32 @@ AC_ARG_ENABLE(debug,
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
|
||||
|
||||
AC_ARG_ENABLE(zend-memory-manager,
|
||||
[ --disable-zend-memory-manager
|
||||
Disable the Zend memory manager - FOR DEVELOPERS ONLY!!],
|
||||
[
|
||||
ZEND_USE_ZEND_ALLOC=$enableval
|
||||
], [
|
||||
ZEND_USE_ZEND_ALLOC=yes
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(maintainer-zts,
|
||||
[ --enable-maintainer-zts Enable thread safety - for code maintainers only],[
|
||||
ZEND_MAINTAINER_ZTS=$enableval
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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_MAINTAINER_ZTS=no
|
||||
ZEND_EXPERIMENTAL_ZTS=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(inline-optimization,
|
||||
[ --disable-inline-optimization
|
||||
If building zend_execute.lo fails, try this switch.],[
|
||||
[ --enable-inline-optimization If you have much memory and are using
|
||||
gcc, you might try this.],[
|
||||
ZEND_INLINE_OPTIMIZATION=$enableval
|
||||
],[
|
||||
ZEND_INLINE_OPTIMIZATION=yes
|
||||
ZEND_INLINE_OPTIMIZATION=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(memory-limit,
|
||||
@@ -167,18 +123,8 @@ AC_ARG_ENABLE(memory-limit,
|
||||
ZEND_MEMORY_LIMIT=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(zend-multibyte,
|
||||
[ --enable-zend-multibyte Compile with zend multibyte support. ], [
|
||||
ZEND_MULTIBYTE=$enableval
|
||||
],[
|
||||
ZEND_MULTIBYTE=no
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING(whether to enable the Zend memory manager)
|
||||
AC_MSG_RESULT($ZEND_USE_ZEND_ALLOC)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable thread-safety)
|
||||
AC_MSG_RESULT($ZEND_MAINTAINER_ZTS)
|
||||
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)
|
||||
@@ -188,9 +134,6 @@ AC_MSG_RESULT($ZEND_MEMORY_LIMIT)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend debugging)
|
||||
AC_MSG_RESULT($ZEND_DEBUG)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend multibyte)
|
||||
AC_MSG_RESULT($ZEND_MULTIBYTE)
|
||||
|
||||
if test "$ZEND_DEBUG" = "yes"; then
|
||||
AC_DEFINE(ZEND_DEBUG,1,[ ])
|
||||
@@ -207,31 +150,26 @@ fi
|
||||
|
||||
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
|
||||
|
||||
if test "$ZEND_USE_ZEND_ALLOC" = "yes"; then
|
||||
AC_DEFINE(USE_ZEND_ALLOC,1,[Use Zend memory manager])
|
||||
else
|
||||
AC_DEFINE(USE_ZEND_ALLOC,0,[Use Zend memory manager])
|
||||
fi
|
||||
|
||||
if test "$ZEND_MAINTAINER_ZTS" = "yes"; then
|
||||
if test "$ZEND_EXPERIMENTAL_ZTS" = "yes"; then
|
||||
AC_DEFINE(ZTS,1,[ ])
|
||||
CFLAGS="$CFLAGS -DZTS"
|
||||
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
|
||||
|
||||
if test "$ZEND_MULTIBYTE" = "yes"; then
|
||||
AC_DEFINE(ZEND_MULTIBYTE, 1, [ ])
|
||||
fi
|
||||
|
||||
changequote({,})
|
||||
if test -n "$GCC" && test "$ZEND_INLINE_OPTIMIZATION" != "yes"; then
|
||||
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9s]*//`
|
||||
INLINE_CFLAGS=`echo $ac_n "$CFLAGS $ac_c" | sed s/-O[0-9]*//`
|
||||
else
|
||||
INLINE_CFLAGS="$CFLAGS"
|
||||
fi
|
||||
@@ -241,59 +179,44 @@ AC_C_INLINE
|
||||
|
||||
AC_SUBST(INLINE_CFLAGS)
|
||||
|
||||
|
||||
dnl test and set the alignment define for ZEND_MM
|
||||
dnl this also does the logarithmic test for ZEND_MM.
|
||||
AC_MSG_CHECKING(for MM alignment and log values)
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
|
||||
typedef union _mm_align_test {
|
||||
void *ptr;
|
||||
double dbl;
|
||||
long lng;
|
||||
} mm_align_test;
|
||||
|
||||
#if (defined (__GNUC__) && __GNUC__ >= 2)
|
||||
#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
|
||||
#else
|
||||
#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
int i = ZEND_MM_ALIGNMENT;
|
||||
int zeros = 0;
|
||||
FILE *fp;
|
||||
|
||||
while (i & ~0x1) {
|
||||
zeros++;
|
||||
i = i >> 1;
|
||||
}
|
||||
|
||||
fp = fopen("conftest.zend", "w");
|
||||
fprintf(fp, "%d %d\n", ZEND_MM_ALIGNMENT, zeros);
|
||||
fclose(fp);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
], [
|
||||
LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1`
|
||||
LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
|
||||
], [], [
|
||||
dnl cross-compile needs something here
|
||||
LIBZEND_MM_ALIGN=8
|
||||
])
|
||||
|
||||
AC_MSG_RESULT(done)
|
||||
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[
|
||||
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
|
||||
])
|
||||
|
||||
+6
-6
@@ -30,7 +30,7 @@
|
||||
".\zend_config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_modules.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
@@ -63,7 +63,7 @@
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_modules.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
@@ -86,7 +86,7 @@
|
||||
".\zend_llist.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_language_parser.tab.h"\
|
||||
".\zend-parser.tab.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
@@ -110,7 +110,7 @@
|
||||
".\zend_config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_modules.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
@@ -168,7 +168,7 @@
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_modules.h"\
|
||||
".\modules.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
@@ -200,7 +200,7 @@
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_modules.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
|
||||
+53
-348
@@ -4,7 +4,7 @@
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=ZendTS - Win32 Release_TSDbg
|
||||
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
|
||||
@@ -13,14 +13,13 @@ CFG=ZendTS - Win32 Release_TSDbg
|
||||
!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_TSDbg"
|
||||
!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 "ZendTS - Win32 Release_TSDbg" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
@@ -96,29 +95,6 @@ LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Output_Dir "ZendTS___Win32_Release_TSDbg"
|
||||
# PROP BASE Intermediate_Dir "ZendTS___Win32_Release_TSDbg"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 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_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 BASE CPP /YX
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /Od /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
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
@@ -126,12 +102,19 @@ LIB32=link.exe -lib
|
||||
# Name "ZendTS - Win32 Release_TS"
|
||||
# Name "ZendTS - Win32 Debug_TS"
|
||||
# Name "ZendTS - Win32 Release_TS_inline"
|
||||
# Name "ZendTS - Win32 Release_TSDbg"
|
||||
# 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
|
||||
@@ -156,18 +139,10 @@ SOURCE=.\zend_constants.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_default_classes.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_dynamic_array.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -192,34 +167,6 @@ SOURCE=.\zend_indent.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -228,22 +175,6 @@ SOURCE=.\zend_llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects_API.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_opcode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -256,14 +187,6 @@ SOURCE=.\zend_ptr_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_qsort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_sprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -272,18 +195,6 @@ SOURCE=.\zend_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -296,6 +207,18 @@ 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
|
||||
@@ -324,10 +247,6 @@ SOURCE=.\zend_constants.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_default_classes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_dynamic_array.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -336,11 +255,11 @@ SOURCE=.\zend_errors.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_exceptions.h
|
||||
SOURCE=.\zend_execute.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.h
|
||||
SOURCE=.\zend_execute_locks.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -372,38 +291,6 @@ SOURCE=.\zend_indent.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_interfaces.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_istdiostream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_iterators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -412,26 +299,6 @@ SOURCE=.\zend_llist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_mm.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_modules.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_object_handlers.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_objects_API.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_operators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -440,30 +307,10 @@ SOURCE=.\zend_ptr_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_qsort.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_reflection_api.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stream.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_strtod.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ts_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.h
|
||||
# End Source File
|
||||
# End Group
|
||||
@@ -472,21 +319,23 @@ SOURCE=.\zend_variables.h
|
||||
# PROP Default_Filter "y"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_parser.y
|
||||
SOURCE=".\zend-parser.y"
|
||||
|
||||
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=.\zend_ini_parser.y
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
|
||||
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_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -494,15 +343,17 @@ BuildCmds= \
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=.\zend_ini_parser.y
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
|
||||
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_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -510,102 +361,17 @@ BuildCmds= \
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=.\zend_ini_parser.y
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
|
||||
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_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=.\zend_ini_parser.y
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_ini_parser.c -v -d -p ini_ zend_ini_parser.y
|
||||
|
||||
"$(InputDir)\zend_ini_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_ini_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_parser.y"
|
||||
|
||||
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
|
||||
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
|
||||
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
|
||||
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend_language_parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend_language_parser.c -v -d -p zend zend_language_parser.y
|
||||
|
||||
"$(InputDir)\zend_language_parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend_language_parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
@@ -618,96 +384,35 @@ BuildCmds= \
|
||||
# PROP Default_Filter "l"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\flex.skl
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ini_scanner.l
|
||||
SOURCE=".\zend-scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=.\zend_ini_scanner.l
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_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_ini_scanner.l
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_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_ini_scanner.l
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=.\zend_ini_scanner.l
|
||||
|
||||
"zend_ini_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pini_ -ozend_ini_scanner.c zend_ini_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend_language_scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "ZendTS - Win32 Release_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend_language_scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Debug_TS"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend_language_scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TS_inline"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend_language_scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendTS - Win32 Release_TSDbg"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend_language_scanner.l"
|
||||
|
||||
"zend_language_scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -B -i -Sflex.skl -Pzend -ozend_language_scanner.c zend_language_scanner.l
|
||||
"zend-scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -+ -B -i -Sflex.skl -Pzend -ozend-scanner.cpp zend-scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
||||
+6
-48
@@ -1,30 +1,12 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.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> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#define ZEND_API
|
||||
#define ZEND_DLEXPORT
|
||||
#define ZEND_DLIMPORT
|
||||
|
||||
@TOP@
|
||||
|
||||
/* these are defined by automake */
|
||||
#undef PACKAGE
|
||||
#undef VERSION
|
||||
|
||||
#undef uint
|
||||
#undef ulong
|
||||
|
||||
@@ -33,8 +15,6 @@
|
||||
|
||||
@BOTTOM@
|
||||
|
||||
#ifndef ZEND_ACCONFIG_H_NO_C_PROTOS
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
@@ -43,14 +23,6 @@
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
# include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
@@ -65,23 +37,19 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifndef zend_isnan
|
||||
#ifdef HAVE_ISNAN
|
||||
#define zend_isnan(a) isnan(a)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN))
|
||||
#elif defined(NAN)
|
||||
#define zend_isnan(a) (((a)==NAN)?1:0)
|
||||
#else
|
||||
#define zend_isnan(a) 0
|
||||
#endif
|
||||
#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)
|
||||
#elif defined(HAVE_FPCLASS)
|
||||
#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF))
|
||||
#else
|
||||
#define zend_isinf(a) 0
|
||||
#endif
|
||||
@@ -96,19 +64,9 @@ int zend_sprintf(char *buffer, const char *format, ...);
|
||||
#define zend_finite(a) (zend_isnan(a) ? 0 : zend_isinf(a) ? 0 : 1)
|
||||
#endif
|
||||
|
||||
#endif /* ifndef ZEND_ACCONFIG_H_NO_C_PROTOS */
|
||||
|
||||
#ifdef NETWARE
|
||||
#ifdef USE_WINSOCK
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SOCKLEN_T
|
||||
#/*This detection against winsock is of no use*/ undef HAVE_SYS_SOCKET_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
*/
|
||||
+4
-31
@@ -2,7 +2,7 @@ dnl $Id$
|
||||
dnl
|
||||
dnl This file contains local autoconf functions.
|
||||
|
||||
AC_DEFUN([ZEND_FP_EXCEPT],[
|
||||
AC_DEFUN(ZEND_FP_EXCEPT,[
|
||||
AC_CACHE_CHECK(whether fp_except is defined, ac_cv_type_fp_except,[
|
||||
AC_TRY_COMPILE([
|
||||
#include <floatingpoint.h>
|
||||
@@ -23,7 +23,7 @@ fp_except x = (fp_except) 0;
|
||||
dnl
|
||||
dnl Check for broken sprintf()
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
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
|
||||
@@ -41,34 +41,7 @@ AC_DEFUN([AC_ZEND_BROKEN_SPRINTF],[
|
||||
AC_DEFINE_UNQUOTED(ZEND_BROKEN_SPRINTF, $ac_result, [Whether sprintf is broken])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl AC_ZEND_C_BIGENDIAN
|
||||
dnl Replacement macro for AC_C_BIGENDIAN
|
||||
dnl
|
||||
AC_DEFUN([AC_ZEND_C_BIGENDIAN],
|
||||
[AC_CACHE_CHECK([whether byte ordering is bigendian], ac_cv_c_bigendian_php,
|
||||
[
|
||||
ac_cv_c_bigendian_php=unknown
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
int main(void)
|
||||
{
|
||||
short one = 1;
|
||||
char *cp = (char *)&one;
|
||||
|
||||
if (*cp == 0) {
|
||||
return(0);
|
||||
} else {
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
], [ac_cv_c_bigendian_php=yes], [ac_cv_c_bigendian_php=no], [ac_cv_c_bigendian_php=unknown])
|
||||
])
|
||||
if test $ac_cv_c_bigendian_php = yes; then
|
||||
AC_DEFINE(WORDS_BIGENDIAN, [], [Define if processor uses big-endian word])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_SET_LIBTOOL_VARIABLE],[
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
+3
-9
@@ -2,7 +2,7 @@ dnl $Id$
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(zend.c)
|
||||
AM_INIT_AUTOMAKE(zend, 0.80A, nodefine)
|
||||
AM_INIT_AUTOMAKE(zend, 0.80A)
|
||||
AM_CONFIG_HEADER(zend_config.h)
|
||||
AM_SANITY_CHECK
|
||||
AM_MAINTAINER_MODE
|
||||
@@ -10,19 +10,13 @@ AC_PROG_CC
|
||||
AM_PROG_LEX
|
||||
AM_PROG_CC_STDC
|
||||
ZEND_VERSION=$VERSION
|
||||
AC_ZEND_C_BIGENDIAN
|
||||
|
||||
dnl We want this one before the checks, so the checks can modify CFLAGS.
|
||||
test -z "$CFLAGS" && auto_cflags=1
|
||||
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
|
||||
sinclude(Zend.m4)
|
||||
|
||||
LIBZEND_BASIC_CHECKS
|
||||
LIBZEND_LIBDL_CHECKS
|
||||
LIBZEND_DLSYM_CHECK
|
||||
|
||||
AM_PROG_LIBTOOL
|
||||
if test "$enable_debug" != "yes"; then
|
||||
@@ -41,9 +35,9 @@ fi
|
||||
LIBZEND_ENABLE_DEBUG
|
||||
LIBZEND_OTHER_CHECKS
|
||||
|
||||
ZEND_EXTRA_LIBS="$LIBS"
|
||||
EXTRA_LIBS="$LIBS"
|
||||
LIBS=""
|
||||
AC_SUBST(ZEND_EXTRA_LIBS)
|
||||
AC_SUBST(EXTRA_LIBS)
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
# Local Variables:
|
||||
|
||||
+165
-272
@@ -1,8 +1,7 @@
|
||||
/* A Lexical scanner generated by flex */
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
/* Scanner skeleton version:
|
||||
* $Header$
|
||||
* vim:ft=lex:
|
||||
*/
|
||||
|
||||
#define FLEX_SCANNER
|
||||
@@ -63,8 +62,6 @@ class istream;
|
||||
#define yyconst
|
||||
#endif
|
||||
|
||||
#undef YY_USE_PROTOS
|
||||
#define YY_USE_PROTOS
|
||||
|
||||
#ifdef YY_USE_PROTOS
|
||||
#define YY_PROTO(proto) proto
|
||||
@@ -99,7 +96,7 @@ class istream;
|
||||
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
|
||||
|
||||
/* Special action meaning "start processing a new file". */
|
||||
#define YY_NEW_FILE yyrestart( SCNG(yy_in) TSRMLS_CC )
|
||||
#define YY_NEW_FILE yyrestart( yyin )
|
||||
|
||||
#define YY_END_OF_BUFFER_CHAR 0
|
||||
|
||||
@@ -110,9 +107,9 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
|
||||
extern int yyleng;
|
||||
%-
|
||||
extern FILE *yyin, *yyout;
|
||||
%*
|
||||
|
||||
|
||||
#define EOB_ACT_CONTINUE_SCAN 0
|
||||
#define EOB_ACT_END_OF_FILE 1
|
||||
#define EOB_ACT_LAST_MATCH 2
|
||||
@@ -143,7 +140,7 @@ extern int yyleng;
|
||||
} \
|
||||
while ( 0 )
|
||||
|
||||
#define unput(c) yyunput( c, yytext_ptr TSRMLS_CC )
|
||||
#define unput(c) yyunput( c, yytext_ptr )
|
||||
|
||||
/* The following is because we cannot portably get our hands on size_t
|
||||
* (without autoconf's help, which isn't available because we want
|
||||
@@ -155,7 +152,7 @@ typedef unsigned int yy_size_t;
|
||||
struct yy_buffer_state
|
||||
{
|
||||
%-
|
||||
struct _zend_file_handle *yy_input_file;
|
||||
FILE *yy_input_file;
|
||||
%+
|
||||
istream* yy_input_file;
|
||||
%*
|
||||
@@ -214,8 +211,7 @@ struct yy_buffer_state
|
||||
};
|
||||
|
||||
%- Standard (non-C++) definition
|
||||
#define yy_current_buffer SCNG(current_buffer)
|
||||
#define yy_hold_char SCNG(_yy_hold_char)
|
||||
static YY_BUFFER_STATE yy_current_buffer = 0;
|
||||
%*
|
||||
|
||||
/* We provide macros for accessing buffer states in case in the
|
||||
@@ -227,50 +223,36 @@ struct yy_buffer_state
|
||||
|
||||
%- Standard (non-C++) definition
|
||||
/* yy_hold_char holds the character lost when yytext is formed. */
|
||||
|
||||
#if 0
|
||||
static char yy_hold_char;
|
||||
|
||||
static int yy_n_chars; /* number of characters read into yy_ch_buf */
|
||||
#endif
|
||||
|
||||
|
||||
int yyleng;
|
||||
|
||||
/* Points to current character in buffer. */
|
||||
#define yy_c_buf_p SCNG(c_buf_p)
|
||||
#define yy_init SCNG(init)
|
||||
#define yy_start SCNG(start)
|
||||
|
||||
#ifdef ZTS
|
||||
#define TSRMLS_D void ***tsrm_ls
|
||||
#define TSRMLS_DC , TSRMLS_D
|
||||
#define TSRMLS_C tsrm_ls
|
||||
#define TSRMLS_CC , TSRMLS_C
|
||||
#else
|
||||
#define TSRMLS_D
|
||||
#define TSRMLS_DC
|
||||
#define TSRMLS_C
|
||||
#define TSRMLS_CC
|
||||
#endif
|
||||
static char *yy_c_buf_p = (char *) 0;
|
||||
static int yy_init = 1; /* whether we need to initialize */
|
||||
static int yy_start = 0; /* 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 ...
|
||||
*/
|
||||
/* static int yy_did_buffer_switch_on_eof; */
|
||||
#define yy_did_buffer_switch_on_eof SCNG(_yy_did_buffer_switch_on_eof)
|
||||
static int yy_did_buffer_switch_on_eof;
|
||||
|
||||
void yyrestart YY_PROTO(( struct _zend_file_handle *input_file TSRMLS_DC ));
|
||||
void yyrestart YY_PROTO(( FILE *input_file ));
|
||||
|
||||
void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer TSRMLS_DC ));
|
||||
void yy_load_buffer_state YY_PROTO(( TSRMLS_D ));
|
||||
YY_BUFFER_STATE yy_create_buffer YY_PROTO(( struct _zend_file_handle *file, int size TSRMLS_DC ));
|
||||
void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b TSRMLS_DC ));
|
||||
void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, struct _zend_file_handle *file TSRMLS_DC ));
|
||||
void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b TSRMLS_DC ));
|
||||
#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer TSRMLS_CC )
|
||||
|
||||
YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size TSRMLS_DC ));
|
||||
YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str TSRMLS_DC ));
|
||||
YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len TSRMLS_DC ));
|
||||
void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
|
||||
void yy_load_buffer_state YY_PROTO(( void ));
|
||||
YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
|
||||
void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
|
||||
void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
|
||||
void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
|
||||
#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
|
||||
|
||||
YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
|
||||
YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
|
||||
YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
|
||||
%*
|
||||
|
||||
static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
|
||||
@@ -282,52 +264,28 @@ static void yy_flex_free YY_PROTO(( void * ));
|
||||
#define yy_set_interactive(is_interactive) \
|
||||
{ \
|
||||
if ( ! yy_current_buffer ) \
|
||||
yy_current_buffer = yy_create_buffer( SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC ); \
|
||||
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
|
||||
yy_current_buffer->yy_is_interactive = is_interactive; \
|
||||
}
|
||||
|
||||
#define yy_set_bol(at_bol) \
|
||||
{ \
|
||||
if ( ! yy_current_buffer ) \
|
||||
yy_current_buffer = yy_create_buffer( SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC ); \
|
||||
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
|
||||
yy_current_buffer->yy_at_bol = at_bol; \
|
||||
}
|
||||
|
||||
#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
|
||||
|
||||
%% yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here
|
||||
#undef yyleng
|
||||
#define yyleng SCNG(yy_leng)
|
||||
#undef yytext
|
||||
#define yytext SCNG(yy_text)
|
||||
#undef yytext_ptr
|
||||
#define yytext_ptr SCNG(yy_text)
|
||||
#undef yyin
|
||||
#define yyin SCNG(yy_in)
|
||||
#undef yyout
|
||||
#define yyout SCNG(yy_out)
|
||||
#undef yy_last_accepting_state
|
||||
#define yy_last_accepting_state SCNG(_yy_last_accepting_state)
|
||||
#undef yy_last_accepting_cpos
|
||||
#define yy_last_accepting_cpos SCNG(_yy_last_accepting_cpos)
|
||||
#undef yy_more_flag
|
||||
#define yy_more_flag SCNG(_yy_more_flag)
|
||||
#undef yy_more_len
|
||||
#define yy_more_len SCNG(_yy_more_len)
|
||||
|
||||
|
||||
%- Standard (non-C++) definition
|
||||
static yy_state_type yy_get_previous_state YY_PROTO(( TSRMLS_D ));
|
||||
static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state TSRMLS_DC ));
|
||||
static int yy_get_next_buffer YY_PROTO(( TSRMLS_D ));
|
||||
static yy_state_type yy_get_previous_state YY_PROTO(( void ));
|
||||
static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
|
||||
static int yy_get_next_buffer YY_PROTO(( void ));
|
||||
static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
|
||||
%*
|
||||
|
||||
#undef TSRMLS_D
|
||||
#undef TSRMLS_DC
|
||||
#undef TSRMLS_C
|
||||
#undef TSRMLS_CC
|
||||
|
||||
/* Done after the current pattern has been matched and before the
|
||||
* corresponding action - sets up yytext.
|
||||
*/
|
||||
@@ -339,17 +297,6 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
|
||||
%% code to copy yytext_ptr to yytext[] goes here, if %array
|
||||
yy_c_buf_p = yy_cp;
|
||||
|
||||
#undef yyleng
|
||||
#undef yytext
|
||||
#undef yytext_ptr
|
||||
#undef yyin
|
||||
#undef yyout
|
||||
#undef yy_last_accepting_state
|
||||
#undef yy_last_accepting_cpos
|
||||
#undef yy_more_flag
|
||||
#undef yy_more_len
|
||||
|
||||
|
||||
%% data tables for the DFA and the user's section 1 definitions go here
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
@@ -366,7 +313,7 @@ extern int yywrap YY_PROTO(( void ));
|
||||
|
||||
%-
|
||||
#ifndef YY_NO_UNPUT
|
||||
static void yyunput YY_PROTO(( int c, char *buf_ptr TSRMLS_DC ));
|
||||
static void yyunput YY_PROTO(( int c, char *buf_ptr ));
|
||||
#endif
|
||||
%*
|
||||
|
||||
@@ -381,30 +328,25 @@ static int yy_flex_strlen YY_PROTO(( yyconst char * ));
|
||||
#ifndef YY_NO_INPUT
|
||||
%- Standard (non-C++) definition
|
||||
#ifdef __cplusplus
|
||||
static int 3 YY_PROTO(( TSRMLS_D ));
|
||||
static int yyinput YY_PROTO(( void ));
|
||||
#else
|
||||
static int input YY_PROTO(( TSRMLS_D ));
|
||||
static int input YY_PROTO(( void ));
|
||||
#endif
|
||||
%*
|
||||
#endif
|
||||
|
||||
#if YY_STACK_USED
|
||||
#define yy_start_stack_ptr SCNG(yy_start_stack_ptr)
|
||||
#define yy_start_stack_depth SCNG(yy_start_stack_depth)
|
||||
#define yy_start_stack SCNG(yy_start_stack)
|
||||
/*
|
||||
static int yy_start_stack_ptr = 0;
|
||||
static int yy_start_stack_depth = 0;
|
||||
static int *yy_start_stack = 0;
|
||||
*/
|
||||
#ifndef YY_NO_PUSH_STATE
|
||||
static void yy_push_state YY_PROTO(( int new_state TSRMLS_DC ));
|
||||
static void yy_push_state YY_PROTO(( int new_state ));
|
||||
#endif
|
||||
#ifndef YY_NO_POP_STATE
|
||||
static void yy_pop_state YY_PROTO(( TSRMLS_D ));
|
||||
static void yy_pop_state YY_PROTO(( void ));
|
||||
#endif
|
||||
#ifndef YY_NO_TOP_STATE
|
||||
static int yy_top_state YY_PROTO(( TSRMLS_D ));
|
||||
static int yy_top_state YY_PROTO(( void ));
|
||||
#endif
|
||||
|
||||
#else
|
||||
@@ -435,29 +377,12 @@ YY_MALLOC_DECL
|
||||
|
||||
/* Copy whatever the last rule matched to the standard output. */
|
||||
|
||||
/* Zend file handle reading */
|
||||
#ifndef ECHO
|
||||
#define ECHO /* There is no output */
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_multibyte_yyinput(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
#else
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
#endif
|
||||
|
||||
#ifndef ECHO
|
||||
%- Standard (non-C++) definition
|
||||
/* This used to be an fputs(), but since the string might contain NUL's,
|
||||
* we now use fwrite().
|
||||
*/
|
||||
#define ECHO (void) fwrite( yytext, yyleng, 1, SCNG(yy_out) )
|
||||
#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
|
||||
%+ C++ definition
|
||||
#define ECHO LexerOutput( yytext, yyleng )
|
||||
%*
|
||||
@@ -497,7 +422,6 @@ YY_MALLOC_DECL
|
||||
%*
|
||||
#endif
|
||||
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
@@ -542,27 +466,25 @@ YY_DECL
|
||||
if ( ! yy_start )
|
||||
yy_start = 1; /* first start state */
|
||||
|
||||
#if 0
|
||||
if ( ! SCNG(yy_in) )
|
||||
if ( ! yyin )
|
||||
%-
|
||||
SCNG(yy_in) = stdin;
|
||||
yyin = stdin;
|
||||
%+
|
||||
SCNG(yy_in) = &cin;
|
||||
yyin = &cin;
|
||||
%*
|
||||
|
||||
if ( ! SCNG(yy_out) )
|
||||
if ( ! yyout )
|
||||
%-
|
||||
SCNG(yy_out) = stdout;
|
||||
yyout = stdout;
|
||||
%+
|
||||
SCNG(yy_out) = &cout;
|
||||
yyout = &cout;
|
||||
%*
|
||||
#endif
|
||||
|
||||
if ( ! yy_current_buffer )
|
||||
yy_current_buffer =
|
||||
yy_create_buffer( SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC );
|
||||
yy_create_buffer( yyin, YY_BUF_SIZE );
|
||||
|
||||
yy_load_buffer_state(TSRMLS_C);
|
||||
yy_load_buffer_state();
|
||||
}
|
||||
|
||||
while ( 1 ) /* loops until end-of-file is reached */
|
||||
@@ -614,8 +536,8 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
* this is the first action (other than possibly a
|
||||
* back-up) that will match for the new input source.
|
||||
*/
|
||||
SCNG(yy_n_chars) = yy_current_buffer->yy_n_chars;
|
||||
yy_current_buffer->yy_input_file = SCNG(yy_in);
|
||||
yy_n_chars = yy_current_buffer->yy_n_chars;
|
||||
yy_current_buffer->yy_input_file = yyin;
|
||||
yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
|
||||
}
|
||||
|
||||
@@ -626,13 +548,13 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
* end-of-buffer state). Contrast this with the test
|
||||
* in input().
|
||||
*/
|
||||
if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars)] )
|
||||
if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
|
||||
{ /* This was really a NUL. */
|
||||
yy_state_type yy_next_state;
|
||||
|
||||
yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
|
||||
|
||||
yy_current_state = yy_get_previous_state(TSRMLS_C);
|
||||
yy_current_state = yy_get_previous_state();
|
||||
|
||||
/* Okay, we're now positioned to make the NUL
|
||||
* transition. We couldn't have
|
||||
@@ -643,7 +565,7 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
* will run more slowly).
|
||||
*/
|
||||
|
||||
yy_next_state = yy_try_NUL_trans( yy_current_state TSRMLS_CC );
|
||||
yy_next_state = yy_try_NUL_trans( yy_current_state );
|
||||
|
||||
yy_bp = yytext_ptr + YY_MORE_ADJ;
|
||||
|
||||
@@ -662,7 +584,7 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
}
|
||||
}
|
||||
|
||||
else switch ( yy_get_next_buffer(TSRMLS_C) )
|
||||
else switch ( yy_get_next_buffer() )
|
||||
{
|
||||
case EOB_ACT_END_OF_FILE:
|
||||
{
|
||||
@@ -697,7 +619,7 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
yy_c_buf_p =
|
||||
yytext_ptr + yy_amount_of_matched_text;
|
||||
|
||||
yy_current_state = yy_get_previous_state(TSRMLS_C);
|
||||
yy_current_state = yy_get_previous_state();
|
||||
|
||||
yy_cp = yy_c_buf_p;
|
||||
yy_bp = yytext_ptr + YY_MORE_ADJ;
|
||||
@@ -705,9 +627,9 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
|
||||
case EOB_ACT_LAST_MATCH:
|
||||
yy_c_buf_p =
|
||||
&yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars)];
|
||||
&yy_current_buffer->yy_ch_buf[yy_n_chars];
|
||||
|
||||
yy_current_state = yy_get_previous_state(TSRMLS_C);
|
||||
yy_current_state = yy_get_previous_state();
|
||||
|
||||
yy_cp = yy_c_buf_p;
|
||||
yy_bp = yytext_ptr + YY_MORE_ADJ;
|
||||
@@ -726,8 +648,8 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
%+
|
||||
yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout )
|
||||
{
|
||||
SCNG(yy_in) = arg_yyin;
|
||||
SCNG(yy_out) = arg_yyout;
|
||||
yyin = arg_yyin;
|
||||
yyout = arg_yyout;
|
||||
yy_c_buf_p = 0;
|
||||
yy_init = 1;
|
||||
yy_start = 0;
|
||||
@@ -756,49 +678,54 @@ yyFlexLexer::yyFlexLexer( istream* arg_yyin, ostream* arg_yyout )
|
||||
yyFlexLexer::~yyFlexLexer()
|
||||
{
|
||||
delete yy_state_buf;
|
||||
yy_delete_buffer( yy_current_buffer TSRMLS_CC );
|
||||
yy_delete_buffer( yy_current_buffer );
|
||||
}
|
||||
|
||||
void yyFlexLexer::switch_streams( istream* new_in, ostream* new_out )
|
||||
{
|
||||
if ( new_in )
|
||||
{
|
||||
yy_delete_buffer( SCNG(yy_current_buffer TSRMLS_CC ) );
|
||||
yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE TSRMLS_CC ) TSRMLS_CC );
|
||||
yy_delete_buffer( yy_current_buffer );
|
||||
yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) );
|
||||
}
|
||||
|
||||
if ( new_out )
|
||||
SCNG(yy_out) = new_out;
|
||||
yyout = new_out;
|
||||
}
|
||||
|
||||
#ifdef YY_INTERACTIVE
|
||||
int yyFlexLexer::LexerInput( char* buf, int /* max_size */ )
|
||||
#else
|
||||
int yyFlexLexer::LexerInput( char* buf, int max_size )
|
||||
#endif
|
||||
{
|
||||
if ( SCNG(yy_in)->eof() || SCNG(yy_in)->fail() )
|
||||
return 0;
|
||||
if ( yyin->eof() || yyin->fail() )
|
||||
return 0;
|
||||
|
||||
if (yy_current_buffer->yy_is_interactive) {
|
||||
SCNG(yy_in)->get( buf[0] );
|
||||
#ifdef YY_INTERACTIVE
|
||||
yyin->get( buf[0] );
|
||||
|
||||
if ( SCNG(yy_in)->eof() )
|
||||
return 0;
|
||||
if ( yyin->eof() )
|
||||
return 0;
|
||||
|
||||
if ( SCNG(yy_in)->bad() )
|
||||
return -1;
|
||||
if ( yyin->bad() )
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
(void) SCNG(yy_in)->read( buf, max_size );
|
||||
return 1;
|
||||
|
||||
if ( SCNG(yy_in)->bad() )
|
||||
return -1;
|
||||
else
|
||||
return SCNG(yy_in)->gcount();
|
||||
}
|
||||
#else
|
||||
(void) yyin->read( buf, max_size );
|
||||
|
||||
if ( yyin->bad() )
|
||||
return -1;
|
||||
else
|
||||
return yyin->gcount();
|
||||
#endif
|
||||
}
|
||||
|
||||
void yyFlexLexer::LexerOutput( const char* buf, int size )
|
||||
{
|
||||
(void) SCNG(yy_out)->write( buf, size );
|
||||
(void) yyout->write( buf, size );
|
||||
}
|
||||
%*
|
||||
|
||||
@@ -811,9 +738,9 @@ void yyFlexLexer::LexerOutput( const char* buf, int size )
|
||||
*/
|
||||
|
||||
%-
|
||||
static int yy_get_next_buffer(TSRMLS_D)
|
||||
static int yy_get_next_buffer()
|
||||
%+
|
||||
int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
int yyFlexLexer::yy_get_next_buffer()
|
||||
%*
|
||||
{
|
||||
register char *dest = yy_current_buffer->yy_ch_buf;
|
||||
@@ -821,7 +748,7 @@ int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
register int number_to_move, i;
|
||||
int ret_val;
|
||||
|
||||
if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars) + 1] )
|
||||
if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
|
||||
YY_FATAL_ERROR(
|
||||
"fatal flex scanner internal error--end of buffer missed" );
|
||||
|
||||
@@ -856,7 +783,7 @@ int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
/* don't do the read, it's not guaranteed to return an EOF,
|
||||
* just force an EOF
|
||||
*/
|
||||
yy_current_buffer->yy_n_chars = SCNG(yy_n_chars) = 0;
|
||||
yy_current_buffer->yy_n_chars = yy_n_chars = 0;
|
||||
|
||||
else
|
||||
{
|
||||
@@ -910,17 +837,17 @@ int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
|
||||
/* Read in more data. */
|
||||
YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
|
||||
SCNG(yy_n_chars), num_to_read );
|
||||
yy_n_chars, num_to_read );
|
||||
|
||||
yy_current_buffer->yy_n_chars = SCNG(yy_n_chars);
|
||||
yy_current_buffer->yy_n_chars = yy_n_chars;
|
||||
}
|
||||
|
||||
if ( SCNG(yy_n_chars) == 0 )
|
||||
if ( yy_n_chars == 0 )
|
||||
{
|
||||
if ( number_to_move == YY_MORE_ADJ )
|
||||
{
|
||||
ret_val = EOB_ACT_END_OF_FILE;
|
||||
yyrestart( SCNG(yy_in) TSRMLS_CC );
|
||||
yyrestart( yyin );
|
||||
}
|
||||
|
||||
else
|
||||
@@ -934,9 +861,9 @@ int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
else
|
||||
ret_val = EOB_ACT_CONTINUE_SCAN;
|
||||
|
||||
SCNG(yy_n_chars) += number_to_move;
|
||||
yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
|
||||
yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
|
||||
yy_n_chars += number_to_move;
|
||||
yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
|
||||
yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
|
||||
|
||||
yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
|
||||
|
||||
@@ -947,9 +874,9 @@ int yyFlexLexer::yy_get_next_buffer(TSRMLS_D)
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
%-
|
||||
static yy_state_type yy_get_previous_state(TSRMLS_D)
|
||||
static yy_state_type yy_get_previous_state()
|
||||
%+
|
||||
yy_state_type yyFlexLexer::yy_get_previous_state(TSRMLS_D)
|
||||
yy_state_type yyFlexLexer::yy_get_previous_state()
|
||||
%*
|
||||
{
|
||||
register yy_state_type yy_current_state;
|
||||
@@ -974,16 +901,13 @@ yy_state_type yyFlexLexer::yy_get_previous_state(TSRMLS_D)
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state TSRMLS_DC )
|
||||
static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
|
||||
#else
|
||||
static yy_state_type yy_try_NUL_trans( yy_current_state TSRMLS_CC )
|
||||
static yy_state_type yy_try_NUL_trans( yy_current_state )
|
||||
yy_state_type yy_current_state;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state TSRMLS_DC )
|
||||
yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
|
||||
%*
|
||||
{
|
||||
register int yy_is_jam;
|
||||
@@ -996,17 +920,14 @@ yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state TSRM
|
||||
%-
|
||||
#ifndef YY_NO_UNPUT
|
||||
#ifdef YY_USE_PROTOS
|
||||
static void yyunput( int c, register char *yy_bp TSRMLS_DC )
|
||||
static void yyunput( int c, register char *yy_bp )
|
||||
#else
|
||||
static void yyunput( c, yy_bp TSRMLS_CC )
|
||||
static void yyunput( c, yy_bp )
|
||||
int c;
|
||||
register char *yy_bp;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yyunput( int c, register char* yy_bp TSRMLS_DC )
|
||||
void yyFlexLexer::yyunput( int c, register char* yy_bp )
|
||||
%*
|
||||
{
|
||||
register char *yy_cp = yy_c_buf_p;
|
||||
@@ -1017,7 +938,7 @@ void yyFlexLexer::yyunput( int c, register char* yy_bp TSRMLS_DC )
|
||||
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
|
||||
{ /* need to shift things up to make room */
|
||||
/* +2 for EOB chars. */
|
||||
register int number_to_move = SCNG(yy_n_chars) + 2;
|
||||
register int number_to_move = yy_n_chars + 2;
|
||||
register char *dest = &yy_current_buffer->yy_ch_buf[
|
||||
yy_current_buffer->yy_buf_size + 2];
|
||||
register char *source =
|
||||
@@ -1029,7 +950,7 @@ void yyFlexLexer::yyunput( int c, register char* yy_bp TSRMLS_DC )
|
||||
yy_cp += (int) (dest - source);
|
||||
yy_bp += (int) (dest - source);
|
||||
yy_current_buffer->yy_n_chars =
|
||||
SCNG(yy_n_chars) = yy_current_buffer->yy_buf_size;
|
||||
yy_n_chars = yy_current_buffer->yy_buf_size;
|
||||
|
||||
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
|
||||
YY_FATAL_ERROR( "flex scanner push-back overflow" );
|
||||
@@ -1050,15 +971,12 @@ void yyFlexLexer::yyunput( int c, register char* yy_bp TSRMLS_DC )
|
||||
|
||||
%-
|
||||
#ifdef __cplusplus
|
||||
static int yyinput(TSRMLS_D)
|
||||
static int yyinput()
|
||||
#else
|
||||
static int input(TSRMLS_C)
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
static int input()
|
||||
#endif
|
||||
%+
|
||||
int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
int yyFlexLexer::yyinput()
|
||||
%*
|
||||
{
|
||||
int c;
|
||||
@@ -1071,7 +989,7 @@ int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
* If this occurs *before* the EOB characters, then it's a
|
||||
* valid NUL; if not, then we've hit the end of the buffer.
|
||||
*/
|
||||
if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[SCNG(yy_n_chars)] )
|
||||
if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
|
||||
/* This was really a NUL. */
|
||||
*yy_c_buf_p = '\0';
|
||||
|
||||
@@ -1080,7 +998,7 @@ int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
int offset = yy_c_buf_p - yytext_ptr;
|
||||
++yy_c_buf_p;
|
||||
|
||||
switch ( yy_get_next_buffer(TSRMLS_C) )
|
||||
switch ( yy_get_next_buffer() )
|
||||
{
|
||||
case EOB_ACT_LAST_MATCH:
|
||||
/* This happens because yy_g_n_b()
|
||||
@@ -1094,7 +1012,7 @@ int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
*/
|
||||
|
||||
/* Reset buffer status. */
|
||||
yyrestart( SCNG(yy_in) TSRMLS_CC );
|
||||
yyrestart( yyin );
|
||||
|
||||
/* fall through */
|
||||
|
||||
@@ -1106,9 +1024,9 @@ int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
if ( ! yy_did_buffer_switch_on_eof )
|
||||
YY_NEW_FILE;
|
||||
#ifdef __cplusplus
|
||||
return yyinput(TSRMLS_C);
|
||||
return yyinput();
|
||||
#else
|
||||
return input(TSRMLS_C);
|
||||
return input();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1131,35 +1049,32 @@ int yyFlexLexer::yyinput(TSRMLS_D)
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yyrestart( struct _zend_file_handle *input_file TSRMLS_DC )
|
||||
void yyrestart( FILE *input_file )
|
||||
#else
|
||||
void yyrestart( input_file TSRMLS_CC )
|
||||
struct _zend_file_handle *input_file;
|
||||
void yyrestart( input_file )
|
||||
FILE *input_file;
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yyrestart( istream* input_file TSRMLS_DC )
|
||||
void yyFlexLexer::yyrestart( istream* input_file )
|
||||
%*
|
||||
{
|
||||
if ( ! yy_current_buffer )
|
||||
yy_current_buffer = yy_create_buffer( SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC );
|
||||
yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
|
||||
|
||||
yy_init_buffer( yy_current_buffer, input_file TSRMLS_CC );
|
||||
yy_load_buffer_state(TSRMLS_C);
|
||||
yy_init_buffer( yy_current_buffer, input_file );
|
||||
yy_load_buffer_state();
|
||||
}
|
||||
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer TSRMLS_DC)
|
||||
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
|
||||
#else
|
||||
void yy_switch_to_buffer( new_buffer TSRMLS_CC)
|
||||
void yy_switch_to_buffer( new_buffer )
|
||||
YY_BUFFER_STATE new_buffer;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer TSRMLS_DC )
|
||||
void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
|
||||
%*
|
||||
{
|
||||
if ( yy_current_buffer == new_buffer )
|
||||
@@ -1170,11 +1085,11 @@ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer TSRMLS_DC )
|
||||
/* Flush out information for old buffer. */
|
||||
*yy_c_buf_p = yy_hold_char;
|
||||
yy_current_buffer->yy_buf_pos = yy_c_buf_p;
|
||||
yy_current_buffer->yy_n_chars = SCNG(yy_n_chars);
|
||||
yy_current_buffer->yy_n_chars = yy_n_chars;
|
||||
}
|
||||
|
||||
yy_current_buffer = new_buffer;
|
||||
yy_load_buffer_state(TSRMLS_C);
|
||||
yy_load_buffer_state();
|
||||
|
||||
/* We don't actually know whether we did this switch during
|
||||
* EOF (yywrap()) processing, but the only time this flag
|
||||
@@ -1187,37 +1102,31 @@ void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer TSRMLS_DC )
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yy_load_buffer_state( TSRMLS_D )
|
||||
void yy_load_buffer_state( void )
|
||||
#else
|
||||
void yy_load_buffer_state(TSRMLS_C)
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
void yy_load_buffer_state()
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yy_load_buffer_state()
|
||||
%*
|
||||
{
|
||||
SCNG(yy_n_chars) = yy_current_buffer->yy_n_chars;
|
||||
yy_n_chars = yy_current_buffer->yy_n_chars;
|
||||
yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
|
||||
SCNG(yy_in) = yy_current_buffer->yy_input_file;
|
||||
yyin = yy_current_buffer->yy_input_file;
|
||||
yy_hold_char = *yy_c_buf_p;
|
||||
}
|
||||
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
YY_BUFFER_STATE yy_create_buffer( struct _zend_file_handle *file, int size TSRMLS_DC )
|
||||
YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
|
||||
#else
|
||||
YY_BUFFER_STATE yy_create_buffer( file, size TSRMLS_CC )
|
||||
struct _zend_file_handle *file;
|
||||
YY_BUFFER_STATE yy_create_buffer( file, size )
|
||||
FILE *file;
|
||||
int size;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size TSRMLS_DC )
|
||||
YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size )
|
||||
%*
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
@@ -1237,7 +1146,7 @@ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size TSRMLS_DC
|
||||
|
||||
b->yy_is_our_buffer = 1;
|
||||
|
||||
yy_init_buffer( b, file TSRMLS_CC );
|
||||
yy_init_buffer( b, file );
|
||||
|
||||
return b;
|
||||
}
|
||||
@@ -1245,16 +1154,13 @@ YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( istream* file, int size TSRMLS_DC
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yy_delete_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
void yy_delete_buffer( YY_BUFFER_STATE b )
|
||||
#else
|
||||
void yy_delete_buffer( b TSRMLS_CC )
|
||||
void yy_delete_buffer( b )
|
||||
YY_BUFFER_STATE b;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
|
||||
%*
|
||||
{
|
||||
if ( ! b )
|
||||
@@ -1271,25 +1177,27 @@ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
|
||||
|
||||
%-
|
||||
#ifndef YY_ALWAYS_INTERACTIVE
|
||||
#ifndef YY_NEVER_INTERACTIVE
|
||||
extern int isatty YY_PROTO(( int ));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yy_init_buffer( YY_BUFFER_STATE b, struct _zend_file_handle *file TSRMLS_DC )
|
||||
void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
|
||||
#else
|
||||
void yy_init_buffer( b, file TSRMLS_CC )
|
||||
void yy_init_buffer( b, file )
|
||||
YY_BUFFER_STATE b;
|
||||
struct _zend_file_handle *file;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
FILE *file;
|
||||
#endif
|
||||
|
||||
%+
|
||||
extern "C" int isatty YY_PROTO(( int ));
|
||||
void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file TSRMLS_DC )
|
||||
void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file )
|
||||
%*
|
||||
|
||||
{
|
||||
yy_flush_buffer( b TSRMLS_CC );
|
||||
yy_flush_buffer( b );
|
||||
|
||||
b->yy_input_file = file;
|
||||
b->yy_fill_buffer = 1;
|
||||
@@ -1301,28 +1209,25 @@ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file TSRMLS_DC )
|
||||
#if YY_NEVER_INTERACTIVE
|
||||
b->yy_is_interactive = 0;
|
||||
#else
|
||||
b->yy_is_interactive = file->handle.stream.interactive;
|
||||
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
b->yy_is_interactive = (file == (istream *) &cin) ? 1 : 0;
|
||||
b->yy_is_interactive = 0;
|
||||
%*
|
||||
}
|
||||
|
||||
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
void yy_flush_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
void yy_flush_buffer( YY_BUFFER_STATE b )
|
||||
#else
|
||||
void yy_flush_buffer( b TSRMLS_CC )
|
||||
void yy_flush_buffer( b )
|
||||
YY_BUFFER_STATE b;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
%+
|
||||
void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
|
||||
%*
|
||||
{
|
||||
if ( ! b )
|
||||
@@ -1343,7 +1248,7 @@ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
b->yy_buffer_status = YY_BUFFER_NEW;
|
||||
|
||||
if ( b == yy_current_buffer )
|
||||
yy_load_buffer_state(TSRMLS_C);
|
||||
yy_load_buffer_state();
|
||||
}
|
||||
%*
|
||||
|
||||
@@ -1351,14 +1256,11 @@ void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b TSRMLS_DC )
|
||||
#ifndef YY_NO_SCAN_BUFFER
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size TSRMLS_DC )
|
||||
YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
|
||||
#else
|
||||
YY_BUFFER_STATE yy_scan_buffer( base, size TSRMLS_CC )
|
||||
YY_BUFFER_STATE yy_scan_buffer( base, size )
|
||||
char *base;
|
||||
yy_size_t size;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
@@ -1383,7 +1285,7 @@ void ***tsrm_ls;
|
||||
b->yy_fill_buffer = 0;
|
||||
b->yy_buffer_status = YY_BUFFER_NEW;
|
||||
|
||||
yy_switch_to_buffer( b TSRMLS_CC );
|
||||
yy_switch_to_buffer( b );
|
||||
|
||||
return b;
|
||||
}
|
||||
@@ -1394,20 +1296,17 @@ void ***tsrm_ls;
|
||||
#ifndef YY_NO_SCAN_STRING
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str TSRMLS_DC )
|
||||
YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
|
||||
#else
|
||||
YY_BUFFER_STATE yy_scan_string( yy_str TSRMLS_CC )
|
||||
YY_BUFFER_STATE yy_scan_string( yy_str )
|
||||
yyconst char *yy_str;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
int len;
|
||||
for ( len = 0; yy_str[len]; ++len )
|
||||
;
|
||||
|
||||
return yy_scan_bytes( yy_str, len TSRMLS_CC );
|
||||
return yy_scan_bytes( yy_str, len );
|
||||
}
|
||||
%*
|
||||
#endif
|
||||
@@ -1416,14 +1315,11 @@ void ***tsrm_ls;
|
||||
#ifndef YY_NO_SCAN_BYTES
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len TSRMLS_DC )
|
||||
YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
|
||||
#else
|
||||
YY_BUFFER_STATE yy_scan_bytes( bytes, len TSRMLS_CC )
|
||||
YY_BUFFER_STATE yy_scan_bytes( bytes, len )
|
||||
yyconst char *bytes;
|
||||
int len;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
YY_BUFFER_STATE b;
|
||||
@@ -1442,7 +1338,7 @@ void ***tsrm_ls;
|
||||
|
||||
buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
|
||||
|
||||
b = yy_scan_buffer( buf, n TSRMLS_CC);
|
||||
b = yy_scan_buffer( buf, n );
|
||||
if ( ! b )
|
||||
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
|
||||
|
||||
@@ -1460,16 +1356,13 @@ void ***tsrm_ls;
|
||||
#ifndef YY_NO_PUSH_STATE
|
||||
%-
|
||||
#ifdef YY_USE_PROTOS
|
||||
static void yy_push_state( int new_state TSRMLS_DC )
|
||||
static void yy_push_state( int new_state )
|
||||
#else
|
||||
static void yy_push_state( new_state TSRMLS_CC )
|
||||
static void yy_push_state( new_state )
|
||||
int new_state;
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
#endif
|
||||
%+
|
||||
void yyFlexLexer::yy_push_state( int new_state TSRMLS_DC )
|
||||
void yyFlexLexer::yy_push_state( int new_state )
|
||||
%*
|
||||
{
|
||||
if ( yy_start_stack_ptr >= yy_start_stack_depth )
|
||||
@@ -1500,9 +1393,9 @@ void yyFlexLexer::yy_push_state( int new_state TSRMLS_DC )
|
||||
|
||||
#ifndef YY_NO_POP_STATE
|
||||
%-
|
||||
static void yy_pop_state(TSRMLS_D)
|
||||
static void yy_pop_state()
|
||||
%+
|
||||
void yyFlexLexer::yy_pop_state(TSRMLS_D)
|
||||
void yyFlexLexer::yy_pop_state()
|
||||
%*
|
||||
{
|
||||
if ( --yy_start_stack_ptr < 0 )
|
||||
@@ -1515,7 +1408,7 @@ void yyFlexLexer::yy_pop_state(TSRMLS_D)
|
||||
|
||||
#ifndef YY_NO_TOP_STATE
|
||||
%-
|
||||
static int yy_top_state(TSRMLS_D)
|
||||
static int yy_top_state()
|
||||
%+
|
||||
int yyFlexLexer::yy_top_state()
|
||||
%*
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
Bug #19859 (__call() does not catch call_user_func_array() calls)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class test
|
||||
{
|
||||
function __call($method,$args)
|
||||
{
|
||||
print "test::__call invoked for method '$method'\n";
|
||||
}
|
||||
}
|
||||
$x = new test;
|
||||
$x->fake(1);
|
||||
call_user_func_array(array($x,'fake'),array(1));
|
||||
call_user_func(array($x,'fake'),2);
|
||||
?>
|
||||
--EXPECT--
|
||||
test::__call invoked for method 'fake'
|
||||
test::__call invoked for method 'fake'
|
||||
test::__call invoked for method 'fake'
|
||||
@@ -1,43 +0,0 @@
|
||||
--TEST--
|
||||
Bug #20240 (order of destructor calls)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class test
|
||||
{
|
||||
public $member;
|
||||
|
||||
function test() {
|
||||
$this->member = 1;
|
||||
register_shutdown_function(array($this, 'destructor'));
|
||||
}
|
||||
|
||||
function destructor() {
|
||||
print __METHOD__ . "\n";
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
print __METHOD__ . "\n";
|
||||
}
|
||||
|
||||
function add() {
|
||||
$this->member += 1;
|
||||
print $this->member."\n";
|
||||
}
|
||||
}
|
||||
|
||||
$t = new test();
|
||||
|
||||
$t->add();
|
||||
$t->add();
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
2
|
||||
3
|
||||
Done
|
||||
test::__destruct
|
||||
test::destructor
|
||||
@@ -1,26 +0,0 @@
|
||||
--TEST--
|
||||
Bug #20242 (Method call in front of class definition)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '>=')) die('skip ZendEngine 2 does not support this'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// THIS IS A WON'T FIX FOR ZE2
|
||||
|
||||
test::show_static();
|
||||
|
||||
$t = new test;
|
||||
$t->show_method();
|
||||
|
||||
class test {
|
||||
static function show_static() {
|
||||
echo "static\n";
|
||||
}
|
||||
function show_method() {
|
||||
echo "method\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
static
|
||||
method
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
Bug #21478 (Zend/zend_alloc.c :: shutdown_memory_manager produces segfault)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed');
|
||||
if (!function_exists('stream_filter_register')) die('skip stream_filter_register() not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class debugfilter extends php_user_filter {
|
||||
function filter($in, $out, &$consumed, $closing) {
|
||||
while ($bucket = stream_bucket_make_writeable($in)) {
|
||||
$bucket->data = strtoupper($bucket->data);
|
||||
stream_bucket_append($out, $bucket);
|
||||
$consumed += strlen($bucket->data);
|
||||
}
|
||||
return PSFS_PASS_ON;
|
||||
}
|
||||
}
|
||||
|
||||
stream_filter_register("myfilter","debugfilter");
|
||||
|
||||
$fp = fopen(dirname(__FILE__)."/test.txt","w");
|
||||
stream_filter_append($fp, "myfilter");
|
||||
stream_filter_append($fp, "myfilter");
|
||||
stream_filter_append($fp, "myfilter");
|
||||
fwrite($fp, "This is a test.\n");
|
||||
print "Done.\n";
|
||||
fclose($fp);
|
||||
// Uncommenting the following 'print' line causes the segfault to stop occuring
|
||||
// print "2\n";
|
||||
readfile(dirname(__FILE__)."/test.txt");
|
||||
unlink(dirname(__FILE__)."/test.txt");
|
||||
?>
|
||||
--EXPECT--
|
||||
Done.
|
||||
THIS IS A TEST.
|
||||
@@ -1,39 +0,0 @@
|
||||
--TEST--
|
||||
Bug #21888 (protected property and protected method of the same name)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
class mom {
|
||||
|
||||
protected $prot = "protected property\n";
|
||||
|
||||
protected function prot() {
|
||||
print "protected method\n";
|
||||
}
|
||||
}
|
||||
|
||||
class child extends mom {
|
||||
|
||||
public function callMom() {
|
||||
$this->prot();
|
||||
}
|
||||
|
||||
public function viewMom() {
|
||||
print $this->prot;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$c = new child();
|
||||
$c->callMom();
|
||||
$c->viewMom();
|
||||
?>
|
||||
--EXPECT--
|
||||
protected method
|
||||
protected property
|
||||
--EXPECT--
|
||||
protected method
|
||||
protected property
|
||||
@@ -1,31 +0,0 @@
|
||||
--TEST--
|
||||
bug #22725 (A derived class can call a parent's protected method that calls a private method)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
private function aPrivateMethod() {
|
||||
echo "Foo::aPrivateMethod() called.\n";
|
||||
}
|
||||
|
||||
protected function aProtectedMethod() {
|
||||
echo "Foo::aProtectedMethod() called.\n";
|
||||
$this->aPrivateMethod();
|
||||
}
|
||||
}
|
||||
|
||||
class Bar extends Foo {
|
||||
public function aPublicMethod() {
|
||||
echo "Bar::aPublicMethod() called.\n";
|
||||
$this->aProtectedMethod();
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Bar;
|
||||
$o->aPublicMethod();
|
||||
?>
|
||||
--EXPECT--
|
||||
Bar::aPublicMethod() called.
|
||||
Foo::aProtectedMethod() called.
|
||||
Foo::aPrivateMethod() called.
|
||||
@@ -1,66 +0,0 @@
|
||||
--TEST--
|
||||
Bug #22836 (returning references to NULL)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function &f()
|
||||
{
|
||||
$x = "foo";
|
||||
var_dump($x);
|
||||
print "'$x'\n";
|
||||
return ($a);
|
||||
}
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$h =& f();
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
string(3) "foo"
|
||||
'foo'
|
||||
|
||||
Notice: Undefined variable: a in %s on line %d
|
||||
|
||||
Strict Standards: Only variable references should be returned by reference in %s on line %d
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Bug #23104 (Hash position not reset for constant arrays)
|
||||
--FILE--
|
||||
<?php
|
||||
function foo($bar = array("a", "b", "c"))
|
||||
{
|
||||
var_dump(current($bar));
|
||||
}
|
||||
foo();
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "a"
|
||||
@@ -1,24 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24436 (isset()/empty() produce errors with non-existent variables in classes)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--INI--
|
||||
error_reporting=2047
|
||||
--FILE--
|
||||
<?php
|
||||
class test {
|
||||
function __construct() {
|
||||
if (empty($this->test[0][0])) { print "test1\n";}
|
||||
if (!isset($this->test[0][0])) { print "test2\n";}
|
||||
if (empty($this->test)) { print "test1\n";}
|
||||
if (!isset($this->test)) { print "test2\n";}
|
||||
}
|
||||
}
|
||||
|
||||
$test1 = new test();
|
||||
?>
|
||||
--EXPECT--
|
||||
test1
|
||||
test2
|
||||
test1
|
||||
test2
|
||||
@@ -1,30 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24635 (crash on dtor calling other functions)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class SiteClass {
|
||||
function __construct() { $this->page = new PageClass(); }
|
||||
}
|
||||
class PageClass {
|
||||
function Display() {
|
||||
$section = new SectionClass("PageClass::Display");
|
||||
}
|
||||
}
|
||||
class SectionClass {
|
||||
function __construct($comment) {
|
||||
$this->Comment = $comment;
|
||||
}
|
||||
function __destruct() {
|
||||
out($this->Comment); // this line doesn't crash PHP
|
||||
out("\n<!-- End Section: " . $this->Comment . "-->"); // this line
|
||||
}
|
||||
}
|
||||
function out($code) { return; }
|
||||
$site = new SiteClass();
|
||||
$site->page->Display();
|
||||
echo "OK\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24699 (Memory Leak with per-class constants)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class TEST { const FOO = SEEK_CUR; };
|
||||
class TEST2 { const FOO = 1; };
|
||||
class TEST3 { const FOO = PHP_VERSION; };
|
||||
print TEST::FOO."\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
1
|
||||
@@ -1,9 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24773 (unset() of integers treated as arrays causes a crash)
|
||||
--FILE--
|
||||
<?php
|
||||
$array = 'test';
|
||||
unset($array["lvl1"]["lvl2"]["b"]);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot unset string offsets in %s on line %d
|
||||
@@ -1,28 +0,0 @@
|
||||
--TEST--
|
||||
Bug #24884 (calling $this->__clone(); crashes php)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class Test {
|
||||
function __copy()
|
||||
{
|
||||
$string = PHP_VERSION;
|
||||
$version = $string{0};
|
||||
if($string < 5)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
$test = new Test();
|
||||
$test2 = $test->__copy();
|
||||
var_dump($test2);
|
||||
?>
|
||||
--EXPECT--
|
||||
object(Test)#2 (0) {
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26010 (private / protected variables get exposed by get_object_vars())
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $private = 'private';
|
||||
protected $protected = 'protected';
|
||||
public $public = 'public';
|
||||
}
|
||||
$data = new foo();
|
||||
$obj_vars = get_object_vars($data);
|
||||
var_dump($obj_vars);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
["public"]=>
|
||||
string(6) "public"
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26077 Memory leaks when creating an instance of an object
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {} new foo();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -1,67 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26166 (__toString() crash when no values returned)
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo
|
||||
{
|
||||
function __toString()
|
||||
{
|
||||
return "Hello World!\n";
|
||||
}
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
private $obj;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->obj = new Foo();
|
||||
}
|
||||
|
||||
function __toString()
|
||||
{
|
||||
return $this->obj->__toString();
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Bar;
|
||||
echo $o;
|
||||
|
||||
echo "===THROW===\n";
|
||||
|
||||
class Error
|
||||
{
|
||||
function __toString() {
|
||||
throw new Exception("This is an error!");
|
||||
}
|
||||
}
|
||||
|
||||
$o = new Error;
|
||||
try {
|
||||
echo $o;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo "Got the exception\n";
|
||||
}
|
||||
|
||||
echo "===NONE===\n";
|
||||
|
||||
class None
|
||||
{
|
||||
function __toString() {
|
||||
}
|
||||
}
|
||||
|
||||
$o = new None;
|
||||
echo $o;
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Hello World!
|
||||
===THROW===
|
||||
Got the exception
|
||||
===NONE===
|
||||
|
||||
Fatal error: Method None::__toString() must return a string value in %sbug26166.php on line %d
|
||||
@@ -1,29 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26229 (getIterator() segfaults when it returns arrays or scalars)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class array_iterator implements IteratorAggregate {
|
||||
public function getIterator() {
|
||||
return array('foo', 'bar');
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new array_iterator;
|
||||
|
||||
try
|
||||
{
|
||||
foreach ($obj as $property => $value)
|
||||
{
|
||||
var_dump($value);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
Objects returned by array_iterator::getIterator() must be traversable or implement interface Iterator
|
||||
===DONE===
|
||||
@@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26281 (switch() crash when condition is a string offset)
|
||||
--FILE--
|
||||
<?php
|
||||
$x = 'abc';
|
||||
switch ($x{0}) {
|
||||
case 'a':
|
||||
echo "no crash\n";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
no crash
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26696 (crash in switch() when string index is used)
|
||||
--FILE--
|
||||
<?php
|
||||
$str = 'asdd/?';
|
||||
$len = strlen($str);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
switch ($str[$i]) {
|
||||
case '?':
|
||||
echo "?+\n";
|
||||
break;
|
||||
default:
|
||||
echo $str[$i].'-';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
a-s-d-d-/-?+
|
||||
===DONE===
|
||||
@@ -1,24 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26697 (calling class_exists on a nonexistent class in __autoload results in segfault)
|
||||
--SKIPIF--
|
||||
<?php if (function_exists('__autoload')) die('skip __autoload() declared in auto_prepend_file');?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function __autoload($name)
|
||||
{
|
||||
echo __METHOD__ . "($name)\n";
|
||||
var_dump(class_exists('NotExistingClass'));
|
||||
echo __METHOD__ . "($name), done\n";
|
||||
}
|
||||
|
||||
var_dump(class_exists('NotExistingClass'));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
__autoload(NotExistingClass)
|
||||
bool(false)
|
||||
__autoload(NotExistingClass), done
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,73 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26698 (Thrown exceptions while evaluting argument to pass as parameter crash PHP)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ini_set("report_memleaks", 0); // the exception thrown in this test results in a memory leak, which is fine
|
||||
|
||||
class Object
|
||||
{
|
||||
function getNone()
|
||||
{
|
||||
throw new Exception('NONE');
|
||||
}
|
||||
}
|
||||
|
||||
class Proxy
|
||||
{
|
||||
function three($a, $b, $c)
|
||||
{
|
||||
}
|
||||
|
||||
function callOne()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three($res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function callTwo()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three(1, $res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function callThree()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = new Object();
|
||||
$this->three(1, 2, $res->getNone());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
echo 'Caught: '.$e->getMessage()."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$p = new Proxy();
|
||||
|
||||
$p->callOne();
|
||||
$p->callTwo();
|
||||
$p->callThree();
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
Caught: NONE
|
||||
Caught: NONE
|
||||
Caught: NONE
|
||||
===DONE===
|
||||
@@ -1,22 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26801 (switch ($a{0}) crash)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = '11';
|
||||
$b = $a{0};
|
||||
switch ($b) {
|
||||
case '-':
|
||||
break;
|
||||
}
|
||||
|
||||
$a = '22';
|
||||
switch ($a{0}) {
|
||||
case '-':
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
===DONE===
|
||||
@@ -1,37 +0,0 @@
|
||||
--TEST--
|
||||
Bug #26802 (Can't call static method using a variable)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function global_func()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
|
||||
$function = 'global_func';
|
||||
$function();
|
||||
|
||||
class foo
|
||||
{
|
||||
static $method = 'global_func';
|
||||
|
||||
static public function foo_func()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* The following is a BC break with PHP 4 where it would
|
||||
* call foo::fail. In PHP 5 we first evaluate static class
|
||||
* properties and then do the function call.
|
||||
*/
|
||||
$method = 'foo_func';
|
||||
foo::$method();
|
||||
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
global_func
|
||||
foo::foo_func
|
||||
===DONE===
|
||||
@@ -1,28 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27268 (Bad references accentuated by clone)
|
||||
--FILE--
|
||||
<?php
|
||||
class A
|
||||
{
|
||||
public function &getA()
|
||||
{
|
||||
return $this->a;
|
||||
}
|
||||
}
|
||||
|
||||
$A = new A;
|
||||
$A->a = array(1);
|
||||
$x = $A->getA();
|
||||
$clone = clone $A;
|
||||
$clone->a = array();
|
||||
print_r($A);
|
||||
?>
|
||||
--EXPECT--
|
||||
A Object
|
||||
(
|
||||
[a] => Array
|
||||
(
|
||||
[0] => 1
|
||||
)
|
||||
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27304
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Staticexample
|
||||
{
|
||||
static function test()
|
||||
{
|
||||
var_dump(isset($this));
|
||||
}
|
||||
}
|
||||
|
||||
$b = new Staticexample();
|
||||
Staticexample::test();
|
||||
$b->test();
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(false)
|
||||
===DONE===
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27598 (list() array key assignment causes HUGE memory leak)
|
||||
--FILE--
|
||||
<?php
|
||||
list($out[0]) = array(1);
|
||||
var_dump($out);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27641 (zend.ze1_compatibility_mode = On causes object properties to be misreported)
|
||||
--SKIPIF--
|
||||
<?php if (version_compare(zend_version(), '2.0.0-dev', '<')) die('skip ZendEngine 2 is needed'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
public $a = "Default for A";
|
||||
public $b = "Default for B";
|
||||
|
||||
function __construct($a, $b) {
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
}
|
||||
function A() {
|
||||
$args = func_get_args();
|
||||
call_user_func_array(Array(&$this, '__construct'), $args);
|
||||
}
|
||||
}
|
||||
|
||||
$t = new A("New A", "New B");
|
||||
print_r($t);
|
||||
print_r(get_class_vars(get_class($t)));
|
||||
print_r(get_object_vars($t));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Strict Standards: Redefining already defined constructor for class A in %sbug27641.php on line %d
|
||||
A Object
|
||||
(
|
||||
[a] => New A
|
||||
[b] => New B
|
||||
)
|
||||
Array
|
||||
(
|
||||
[a] => Default for A
|
||||
[b] => Default for B
|
||||
)
|
||||
Array
|
||||
(
|
||||
[a] => New A
|
||||
[b] => New B
|
||||
)
|
||||
@@ -1,10 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27731 (error_reporing() call inside @ block does not work correctly)
|
||||
--FILE--
|
||||
<?php
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
@error_reporting(E_WARNING);
|
||||
var_dump(error_reporting());
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2)
|
||||
@@ -1,72 +0,0 @@
|
||||
--TEST--
|
||||
Bug #27798 (private / protected variables not exposed by get_object_vars() inside class)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Base
|
||||
{
|
||||
public $Foo = 1;
|
||||
protected $Bar = 2;
|
||||
private $Baz = 3;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
echo __METHOD__ . "\n";
|
||||
var_dump(get_object_vars($this));
|
||||
}
|
||||
}
|
||||
|
||||
class Child extends Base
|
||||
{
|
||||
private $Baz = 4;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
echo __METHOD__ . "\n";
|
||||
var_dump(get_object_vars($this));
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(get_object_vars(new Base));
|
||||
var_dump(get_object_vars(new Child));
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
Base::__construct
|
||||
array(3) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
["Baz"]=>
|
||||
int(3)
|
||||
}
|
||||
array(1) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
Base::__construct
|
||||
array(3) {
|
||||
["Baz"]=>
|
||||
int(4)
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
Child::__construct
|
||||
array(3) {
|
||||
["Baz"]=>
|
||||
int(4)
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
["Bar"]=>
|
||||
int(2)
|
||||
}
|
||||
array(1) {
|
||||
["Foo"]=>
|
||||
int(1)
|
||||
}
|
||||
===DONE===
|
||||
@@ -1,23 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28377 (debug_backtrace is intermittently passing args)
|
||||
--FILE--
|
||||
<?php
|
||||
function doit($a, $b)
|
||||
{
|
||||
$trace = debug_backtrace();
|
||||
custom_callback('dereferenced', $trace);
|
||||
custom_callback('direct', debug_backtrace());
|
||||
}
|
||||
|
||||
function custom_callback($traceName, $btInfo)
|
||||
{
|
||||
echo $traceName ." -- args: ";
|
||||
echo isset($btInfo[0]['args']) ? count($btInfo[0]['args']) : 'does not exist';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
doit('a','b');
|
||||
?>
|
||||
--EXPECT--
|
||||
dereferenced -- args: 2
|
||||
direct -- args: 2
|
||||
@@ -1,65 +0,0 @@
|
||||
--TEST--
|
||||
Bug #28442 (Changing a static variables in a class changes it across sub/super classes.)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class ClassA
|
||||
{
|
||||
static $prop;
|
||||
}
|
||||
|
||||
class ClassB extends ClassA
|
||||
{
|
||||
static $prop;
|
||||
}
|
||||
|
||||
class ClassC extends ClassB
|
||||
{
|
||||
}
|
||||
|
||||
echo "===INIT===\n";
|
||||
ClassA::$prop = 'A';
|
||||
ClassB::$prop = 'B';
|
||||
ClassC::$prop = 'C';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetA===\n";
|
||||
ClassA::$prop = 'A2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetB===\n";
|
||||
ClassB::$prop = 'B2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
echo "===SetC===\n";
|
||||
ClassC::$prop = 'C2';
|
||||
var_dump(ClassA::$prop);
|
||||
var_dump(ClassB::$prop);
|
||||
var_dump(ClassC::$prop);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
===INIT===
|
||||
string(1) "A"
|
||||
string(1) "C"
|
||||
string(1) "C"
|
||||
===SetA===
|
||||
string(2) "A2"
|
||||
string(1) "C"
|
||||
string(1) "C"
|
||||
===SetB===
|
||||
string(2) "A2"
|
||||
string(2) "B2"
|
||||
string(2) "B2"
|
||||
===SetC===
|
||||
string(2) "A2"
|
||||
string(2) "C2"
|
||||
string(2) "C2"
|
||||
===DONE===
|
||||
Loaded 100 of 4163 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user