mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-08 01:37:30 +00:00
Compare commits
1
Commits
dev
..
CLOSED_BETA
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6bd3ba9bf |
No files matched your search
@@ -0,0 +1,11 @@
|
||||
If you think you've found a bug in PHP3, you can report it on the bug
|
||||
reporting page at:
|
||||
http://www.php.net/
|
||||
|
||||
Current Known Bugs:
|
||||
|
||||
* split() function doesn't return regex errors nicely
|
||||
* Preprocessed scripts don't work with require() and define()
|
||||
* unset() doesn't actually erase the variables it just marks them as uninitialized
|
||||
* Some parts in the language core prevent more than 256 arguments in function
|
||||
calls from being possible
|
||||
@@ -0,0 +1,624 @@
|
||||
Noticeable Changes between PHP/FI 2.0 and PHP 3.0
|
||||
=================================================
|
||||
|
||||
This file was designed to be viewed with a tab size of 4 characters.
|
||||
|
||||
This file is divided into 4 sections:
|
||||
1. Downwards incompatible language changes. This section includes all of
|
||||
the changes in the core language which may require people to modify
|
||||
their scripts before using them with PHP 3.0. It does NOT list
|
||||
changes made in the behavior of specific functions.
|
||||
2. New language features. This section includes all of the new additions
|
||||
to the core language, that may be used to enhance scripts designed for
|
||||
PHP 3.0. Likewise, it does not include a listing of new functions.
|
||||
3. Structural changes not directly effecting the end user. The core
|
||||
of PHP 3.0 is a complete rewrite. As such, many issues effecting
|
||||
PHP/FI 2.0 were addressed and vastly improved in this version,
|
||||
resulting in a much more stable and efficient implementation. This
|
||||
section lists these changes in design.
|
||||
4. Other changes that don't fit in any of the above categories.
|
||||
|
||||
Please remember that PHP 3.0's core is a complete rewrite, and thus,
|
||||
there may be other undocumented incompatibilities we haven't thought
|
||||
of ourselves. If you think you've found a incompatibility (or a new
|
||||
feature) which is not listed here, please mail us at
|
||||
php-dev@php.iquest.net.
|
||||
|
||||
|
||||
|
||||
- Zeev
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Downwards incompatible language changes
|
||||
=======================================
|
||||
|
||||
[1] The close-PHP tag has changed from > to ?>
|
||||
|
||||
This means that instead of writing:
|
||||
|
||||
<?echo $title;>
|
||||
|
||||
You should write:
|
||||
|
||||
<?echo $title;?>
|
||||
|
||||
PHP3 also includes support for a longer-form start tag that is
|
||||
XML-compliant:
|
||||
|
||||
<?php echo $title;?>
|
||||
|
||||
The ability to use the short start tag ('<?') can be turned on and
|
||||
off using the short_tags() function. Whether it is enabled or not by
|
||||
default is a compile-time option (normally set to enabled by default).
|
||||
|
||||
|
||||
[2] Semicolons in if/elseif/else must be replaced with colons.
|
||||
|
||||
For example, the equivalent of:
|
||||
|
||||
if (expr);
|
||||
statements
|
||||
...
|
||||
elseif (expr);
|
||||
statements
|
||||
...
|
||||
else;
|
||||
statements
|
||||
endif;
|
||||
|
||||
in PHP 3.0 would be:
|
||||
|
||||
if (expr):
|
||||
statements
|
||||
...
|
||||
elseif (expr):
|
||||
statements
|
||||
...
|
||||
else:
|
||||
statements
|
||||
endif;
|
||||
|
||||
Note that the endif is followed by a semicolon and not a colon even in
|
||||
PHP 3.0, which marks the end of the entire IF sentence.
|
||||
|
||||
Also note that the implementation of the colon-mode and curly-braces
|
||||
mode in PHP 3.0 is identical, one isn't buggier than the other (note
|
||||
that I'm not saying they're not buggy, though :)
|
||||
|
||||
|
||||
[3] Semicolons in while loops must also be replaced with colons.
|
||||
|
||||
For example, the equivalent of:
|
||||
|
||||
while (expr);
|
||||
statements
|
||||
...
|
||||
endwhile;
|
||||
|
||||
in PHP 3.0 would be:
|
||||
|
||||
while (expr):
|
||||
statements
|
||||
...
|
||||
endwhile;
|
||||
|
||||
Note that the endwhile is followed by a semicolon and not a colon even
|
||||
in PHP 3.0, which marks the end of the WHILE sentence. As with the IF
|
||||
statement, the implementation of the colon-mode and curly-braces mode
|
||||
in PHP 3.0 is identical, one isn't buggier than the other.
|
||||
|
||||
Also note that failing to change the semicolon to a colon can result in
|
||||
scripts that get stuck in the while loop because the loop-condition never
|
||||
changes.
|
||||
|
||||
|
||||
[4] $foo[0] is no longer identical to $foo.
|
||||
|
||||
In PHP/FI 2.0, a side-effect of the implementation caused $foo[0] to be
|
||||
identical to $foo. This is not the case in PHP 3.0.
|
||||
|
||||
|
||||
[5] Expressions determine their types differently.
|
||||
|
||||
The way expressions are evaluated has changed radically in PHP 3.0.
|
||||
Expressions are no longer given the type of the left argument, but are
|
||||
assigned types taking both types into account, and regardless of which
|
||||
is on the left side and which is on the right side. On simple scripts
|
||||
that should probably not effect you, but if you've relied on this fact
|
||||
(even without realizing you do) it may change the way your scripts work.
|
||||
Consider the next example:
|
||||
|
||||
$a[0]=5;
|
||||
$a[1]=7;
|
||||
|
||||
$key = key($a);
|
||||
while ("" != $key) {
|
||||
echo "$key\n";
|
||||
next($a);
|
||||
}
|
||||
|
||||
|
||||
In PHP/FI 2.0, this would display both of $a's indices. In PHP 3.0, it
|
||||
wouldn't display anything. The reason is that in PHP/FI 2.0, because the
|
||||
left argument's type was string, a string comparison was made, and indeed
|
||||
"" does not equal "0", and the loop went through. In PHP 3.0, when a
|
||||
string is compared with an integer, an integer comparison is made (the
|
||||
string is converted to an integer). This results in comparing atoi("")
|
||||
which is 0, and $key which is also 0, and since 0==0, the loop doesn't
|
||||
go through even once. The fix for this is simple, by replacing the
|
||||
while statement with:
|
||||
|
||||
while ("" != stringval($key)) {
|
||||
|
||||
This would first convert the integer 0 to a string "0", and then
|
||||
compare "" and "0", which are not equal, and the loop would go through
|
||||
as expected. As mentioned later, casting operators are supported in
|
||||
PHP 3.0 for a quicker and more readable way of changing variables'
|
||||
types. For example, you could use:
|
||||
|
||||
while ("" != (string)$key) {
|
||||
|
||||
|
||||
[6] The structure of error messages has changed.
|
||||
|
||||
Although the error messages are usually more accurate, you won't be shown
|
||||
the actual line of text and actual place in which the error occured.
|
||||
You'll be supplied with the line number in which the error has occured,
|
||||
though.
|
||||
|
||||
|
||||
[7] The format string argument to echo is no longer supported.
|
||||
|
||||
Use printf(format,arg1,arg2,arg3,...) instead (unlimited arguments).
|
||||
|
||||
|
||||
[8] The use of read-mode $array[] is no longer supported.
|
||||
|
||||
That is, you cannot traverse an array by having a loop that does $data =
|
||||
$array[]. Use current() and next() instead. Also, $array1[] = $array2
|
||||
does not append the values of $array2 to $array1, but appends $array2
|
||||
as the last entry of $array1 (see the multidimensional array support).
|
||||
|
||||
|
||||
[9] Apache versions older than 1.2 are not supported anymore.
|
||||
|
||||
The apache module requires apache 1.2 or later (1.3-beta is supported).
|
||||
|
||||
|
||||
[10] Indirect references inside quoted strings
|
||||
|
||||
PHP2-style indirect reference inside quoted strings is no longer
|
||||
supported. That is, if $foo="bar", and $bar="abc", in PHP2,
|
||||
"$$foo" would print out "abc". In PHP3, this would print
|
||||
"$bar" (the contents of $foo is replaced with "bar").
|
||||
To use indirect reference in PHP3 inside quoted strings, you should use
|
||||
the new notation: "${$foo}". The standard $$foo notation will work
|
||||
outside of the quoted string.
|
||||
|
||||
[11]
|
||||
Some functions have changed names, are missing, or have been deprecated
|
||||
by other functions
|
||||
|
||||
As a whole new rewrite, written by many more people and supporting many
|
||||
more APIs than it's predecessor, there's a good chance some of the functions
|
||||
you're used to from PHP/FI 2 aren't available in release 3, or have changed
|
||||
names. Many functions that do exist behave a bit differently, mainly
|
||||
because they return different values for errors (false) but also for other
|
||||
reasons. We can't list all of these functions here, simply because drawing
|
||||
a full comparison between the function sets of the two versions is way too
|
||||
much work. If a converted PHP/FI 2 script doesn't work for you, nothing
|
||||
can replace the good old human eye going over the code, doublechecking
|
||||
with the online manual that each function still does what you expected it
|
||||
to do.
|
||||
|
||||
[12] Other incompatibilities.
|
||||
|
||||
It's not too unlikely that other documented behavior of PHP2 has changed
|
||||
in this release. If you think you've found an example, please mail
|
||||
us at php-dev@php.iquest.net. Even if you've found an undocumented
|
||||
feature of PHP2 that stopped working in PHP3, we'd like to know about it
|
||||
(although it's more than likely that it will not be supported).
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
New Language Features
|
||||
=====================
|
||||
|
||||
[1] Expressions
|
||||
|
||||
PHP 3.0 includes a rich implementation of expressions, much more advanced
|
||||
than this of 2.0. Just about any complex C-like or perl-like expression
|
||||
would work. Support was added for assignment operators (+=, -=, *= etc),
|
||||
pre and post increment/decerement (e.g. $i++, ++$i) and the questionmark
|
||||
operator ( (expr?expr:expr) ). Every assignment is now an expression
|
||||
with a value, which means stuff like $a = $b = $c = $d = 0; would work.
|
||||
It is difficult to describe the power of expressions within a few lines
|
||||
of text, but if you're familiar with them, you probably get the picture.
|
||||
|
||||
|
||||
[2] for loops are now supported.
|
||||
|
||||
for loops were fairly difficult to implement (in fact, we didn't find
|
||||
any parallel interpreter that supports for loops anywhere (no, perl is
|
||||
not an interpreter)). The bottom line is that for loops work, and are
|
||||
around 5% slower than comparable while loops (that may vary), but often
|
||||
they're much nicer.
|
||||
|
||||
The syntax is identical to the one of C:
|
||||
|
||||
for (expr; expr; expr) statement;
|
||||
|
||||
or
|
||||
|
||||
for (expr; expr; expr) { statements ... }
|
||||
|
||||
The first expression is executed the first time the loop is encountered,
|
||||
the loop is run as long as the second expression is evaluated as TRUE,
|
||||
and after each iteration, the 3rd expression is evaluated.
|
||||
|
||||
Colon-mode FOR loops are also supported:
|
||||
for (expr; expr; expr):
|
||||
statements
|
||||
...
|
||||
endfor;
|
||||
|
||||
|
||||
[3] do..while(expr) loops are now supported.
|
||||
|
||||
Like with its C parallel, the statements inside a do..while loop are
|
||||
run once the first time the loop is encountered, and then as long as
|
||||
the expression evaluates as true.
|
||||
|
||||
For example:
|
||||
|
||||
do {
|
||||
statements;
|
||||
} while ($i++ < $max);
|
||||
|
||||
|
||||
[4] break and continue statements are now supported inside loops.
|
||||
|
||||
You can break out of loops, or continue to the next iteration of the
|
||||
loop using these statements. A special feature of PHP is the ability
|
||||
to specify an expression argument to break or continue, which specifies
|
||||
how many loops you want to break out from or continue to. For example:
|
||||
|
||||
for ($i=0; $i<10; $i++) {
|
||||
for ($j=0; $j<10; $j++) {
|
||||
if ($j>5)
|
||||
break;
|
||||
if ($i>5)
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
The first break statement would end the inner loop every time $j is
|
||||
greater than 5. The second break statement would end both the inner
|
||||
and outer loop when $i is greater than 5.
|
||||
|
||||
Note: For this matter, switch statements are considered as loops. So
|
||||
if you write "break 2;" inside a switch statement, you would be asking
|
||||
to break out of the switch, and the innermost loop in which is nested.
|
||||
|
||||
|
||||
[5] Switched to C-style declaration of functions.
|
||||
|
||||
Here's a pretty useless function which makes a good example:
|
||||
|
||||
function concat($str1,$str2)
|
||||
{
|
||||
return $str1.$str2;
|
||||
}
|
||||
|
||||
NOTE: The old style function definition is still supported, to
|
||||
allow easier upgrading from PHP/FI 2.0 scripts. Simply
|
||||
change 'function' to 'old_function' for these functions.
|
||||
|
||||
|
||||
[6] OOP support
|
||||
|
||||
Classes and inheritance are supported to a limited extent in PHP 3.0.
|
||||
Here's how to declare a simple class:
|
||||
|
||||
class simple_class {
|
||||
var $property1,$property2;
|
||||
var $property3=5;
|
||||
|
||||
function display() {
|
||||
printf("p1=%d, p2=%d, p3=%d\n",
|
||||
$this->property1,
|
||||
$this->property2,
|
||||
$this->property3);
|
||||
}
|
||||
function init($p1,$p2) {
|
||||
$this->property1 = $p1;
|
||||
$this->property2 = $p2;
|
||||
}
|
||||
};
|
||||
|
||||
Here's how to create an object of that class:
|
||||
|
||||
$obj = new simple_class;
|
||||
|
||||
At this point, $obj is an object with 2 uninitialized variables, 1
|
||||
initialized variable, and 2 member functions. No protection is made on
|
||||
the internals of the object, and using its properties is simple:
|
||||
|
||||
$obj->property1 = 7;
|
||||
|
||||
would assign 7 to $property1 inside $obj. Calling member functions is
|
||||
also simple:
|
||||
|
||||
$obj->display()
|
||||
|
||||
would run the display() member function of $obj. Note that the
|
||||
implementation of display() uses the special variable $this, which is
|
||||
replaced with the object the function is called on.
|
||||
|
||||
Inheritance is pretty simple too:
|
||||
|
||||
class complex_class extends simple_class {
|
||||
var $property4="test";
|
||||
|
||||
function display() {
|
||||
printf("p1=%d, p2=%d, p3=%d, p4=%d\n",
|
||||
$this->property1,
|
||||
$this->property2,
|
||||
$this->property3,
|
||||
$this->property4);
|
||||
}
|
||||
}
|
||||
|
||||
Basically, the class complex_class inherits everything from its parent,
|
||||
simple_class, except properties or member functions which override the
|
||||
ones in the parent. In this example, since we supply an alternative
|
||||
display() function, it would be used with complex_class objects instead
|
||||
of the display() function that was declared in simple_class. On the other
|
||||
hand, since we don't supply an alternative init() function, complex_class
|
||||
objects would have the same init() function as simple_class objects do.
|
||||
|
||||
As with expressions, it's impossible to teach OOP in a few lines, and
|
||||
personally I'm unclear as to how useful this would be in day to day
|
||||
scripting. If you like this, play with this until you figure it out :)
|
||||
|
||||
Objects can reside in arrays, and can contain arrays. However,
|
||||
a limitation of the current implementation doesn't allow an object
|
||||
to contain an array of objects (actually, this is allowed, but
|
||||
there's no way to address the properties of such an object directly,
|
||||
but only indirectly). For example, assuming $a[3] is an object,
|
||||
$a[3]->b[2] is an object as well, you can't address the properties
|
||||
of $a[3]->b[2] (i.e. you can't write $a[3]->b[2]->foo = "bar", for
|
||||
instance).
|
||||
|
||||
|
||||
[7] Function pointers are now supported.
|
||||
|
||||
A simple illustrative example:
|
||||
|
||||
$func_ptr = "time";
|
||||
$current_time = $func_ptr();
|
||||
|
||||
is identical to
|
||||
|
||||
$current_time = time();
|
||||
|
||||
|
||||
[8] Indirect references are much more powerful.
|
||||
|
||||
For example, one can use the dollar operator an infinite amount of times:
|
||||
|
||||
$a = "b";
|
||||
$b = "c";
|
||||
$c = "d";
|
||||
$d = "e";
|
||||
$e = "Testing\n";
|
||||
|
||||
echo $$$$$a;
|
||||
|
||||
Would display $e's content, which is "Testing\n".
|
||||
|
||||
In addition, one can use complex expressions to generate variable names
|
||||
using a perl-like notation:
|
||||
|
||||
$i="123";
|
||||
${"test".$i} = 5;
|
||||
|
||||
would assign 5 to $test123.
|
||||
|
||||
[9] A string concatenation operator was added, '+' no longer concatenates strings.
|
||||
|
||||
A perl-like string concatenation operator was added, the '.' operator.
|
||||
It converts both of its arguments to strings, and concatenates them.
|
||||
For example:
|
||||
|
||||
$result = "abcd".5;
|
||||
|
||||
assigns "abcd5" to result. Note that under PHP 3.0, the '+' operator
|
||||
no longer performs concatenation if its arguments are strings. Use
|
||||
the '.' operator instead.
|
||||
|
||||
[10] Supports passing function arguments by references instead of by value.
|
||||
|
||||
Support for passing function arguments by reference instead of by value
|
||||
has been added. This doesn't result in having to change the function
|
||||
implementations in any way, but, when calling the function, you can
|
||||
decide on whether the variable you supply would actually be changed by
|
||||
the function, or a copy of it.
|
||||
|
||||
Example:
|
||||
|
||||
function inc($arg)
|
||||
{
|
||||
$arg++;
|
||||
}
|
||||
|
||||
$i=0;
|
||||
inc($i); # here $i in the outer scope wouldn't change, and remain 0
|
||||
inc(&$i); # here $i is passed by reference, and would change to 1
|
||||
|
||||
|
||||
[11] Support for multidimensional arrays.
|
||||
|
||||
(Or as Andi calls them, 'hyperdimensional variables'.)
|
||||
|
||||
The easiest way to define this support of PHP 3.0 is inductive -
|
||||
arrays can contain any type of variables, including other arrays.
|
||||
A simple example:
|
||||
|
||||
$a[0]=5;
|
||||
$a[1]["testing"]=17;
|
||||
$b["foo"]=$a;
|
||||
|
||||
Ok, so it may be not so simple. Play with it, it's pretty powerful.
|
||||
|
||||
|
||||
[12] Array initialization is now supported.
|
||||
|
||||
For example, let's say you want to initialize a lookup table to convert
|
||||
number to month names:
|
||||
|
||||
$months = array("January", "February", "March",
|
||||
"April", "May", "June", "July", "August",
|
||||
"September", "October", "November", "December");
|
||||
|
||||
would assign $months[0] to be January, $months[1] to be February, etc.
|
||||
Alternately, you may want the count to start at '1' instead of 0.
|
||||
You can do so easily:
|
||||
|
||||
$months = array(1=>"January", "February", "March",
|
||||
"April", "May", "June", "July", "August",
|
||||
"September", "October", "November", "December");
|
||||
|
||||
Also, you can specify an index for every entry, not just the first one:
|
||||
|
||||
$first_names = array("Doe"=>"John", "Gates"=>"William",
|
||||
"Clinton"=>"Bill" });
|
||||
|
||||
would assign $first_names["Doe"]="John", etc.
|
||||
|
||||
|
||||
[13] Perl style lists now supported.
|
||||
|
||||
Multiple values from arrays may now be assigned into several
|
||||
variables using one assignment. For example:
|
||||
|
||||
$str = "johndoe:x:555:555:Doe, John:/home/johndoe:/bin/tcsh";
|
||||
|
||||
list($username,$passwd,$uid,$gid,$realname,$homedir,$shell) =
|
||||
explode(":",$str);
|
||||
|
||||
Would assign 'johndoe' into $username, 'x' into $passwd, etc.
|
||||
|
||||
|
||||
[14] Colons are supported in 'case' and 'default' statements.
|
||||
|
||||
For example:
|
||||
|
||||
switch($value) {
|
||||
case 'A':
|
||||
statement;
|
||||
break;
|
||||
case 'B':
|
||||
statement;
|
||||
break;
|
||||
case 'C':
|
||||
statement;
|
||||
/* fall-through */
|
||||
default:
|
||||
statement;
|
||||
}
|
||||
|
||||
Semicolons are still supported, but when writing new scripts, they
|
||||
should be phased out in favour of colons.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Non Language Related New Features
|
||||
=================================
|
||||
|
||||
[1] Persistent resource lists.
|
||||
|
||||
In plain english this means that there's now an easy way of writing the
|
||||
SQL drivers so that they don't open and close the SQL link every time,
|
||||
but instead open it the first time it's required, and then use it on
|
||||
every later hit. As of PHP 3.0a1, only the MySQL, mSQL and PostgresSQL
|
||||
drivers have been changed (rewritten) to take advantage of this option.
|
||||
To use it, use mysql_pconnect() instead of mysql_connect() (or the
|
||||
equivalents for the two other databases).
|
||||
|
||||
|
||||
[2] Configuration file.
|
||||
|
||||
PHP now has its own configuration file, and many compile-time options
|
||||
of PHP2 are now configurable at runtime.
|
||||
|
||||
|
||||
[3] Syntax Highlighting.
|
||||
|
||||
A syntax highlighter has been built into PHP 3.0, which means PHP 3.0 can
|
||||
display your code, syntax highlighted, instead of executing it.
|
||||
There are currently two ways to use the syntax highlighter. One is to
|
||||
use the show_source() statement. This statement is identical to the
|
||||
include() statement, except instead of executing the file, it displays
|
||||
its source syntax highlighted.
|
||||
The second way is possible only when running as an apache module, and is
|
||||
to define a special extension for PHP 3.0 source files (e.g. .php3s)
|
||||
and instruct apache to automatically syntax highlight them.
|
||||
|
||||
|
||||
[4] Loadable modules.
|
||||
|
||||
This would have a huge impact on the Windows version, and would probably
|
||||
be used in the UNIX environment as well. One can now add PHP internal
|
||||
functions in runtime by loading a dynamic module. This is known to work
|
||||
under Solaris, Linux and Win32 at this time, but would be ported to any
|
||||
other capable platform if an incompatability is found.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Other Interesting Issues
|
||||
========================
|
||||
|
||||
|
||||
[1] Improved performance.
|
||||
|
||||
The performance of PHP 3.0 is much better than the one of PHP/FI 2.0.
|
||||
Memory consumption has been dramatically reduced in many cases, due
|
||||
to the use of an internal memory manager, instead of apache's pools.
|
||||
Speedwise, PHP 3.0 is somewhere between 2 and 3 times faster than
|
||||
PHP/FI 2.0.
|
||||
|
||||
|
||||
[2] More reliable parser.
|
||||
|
||||
After PHP 3.0 is well tested, it'll be pretty safe to say that it's
|
||||
more reliable than PHP/FI 2.0 is. While PHP/FI 2.0 performed well on
|
||||
simple, and fairly complex scripts, a fundamental design difference
|
||||
from PHP 3.0 makes it more prone to errors. In PHP 3.0, obscure parser
|
||||
problems are much less likely.
|
||||
|
||||
|
||||
[3] Improved C API.
|
||||
|
||||
If you're a C coder, adding functionality to PHP was never easier.
|
||||
A pretty well documented API is available (apidoc.txt), and you no longer
|
||||
have to touch the parser or scanner code when adding your function.
|
||||
Also, it's more complicated to 'go wrong' when implementing a PHP3
|
||||
function than it was in PHP2 (no stack to maintain) - but of course,
|
||||
you can mess up here too :)
|
||||
|
||||
|
||||
[4] Name change.
|
||||
|
||||
PHP/FI 2.0 was renamed to PHP 3.0, and the meaning has changed from
|
||||
'Personal Home Pages / Forms Interpreter' to 'PHP: Hypertext Preprocessor'.
|
||||
'Personal' home pages was an understatement for PHP/FI 2.0, and is
|
||||
definitely an understatement for PHP 3.0.
|
||||
+27
-111
@@ -5,9 +5,8 @@ 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
|
||||
@@ -44,9 +43,9 @@ Exceptions:
|
||||
for efficiency and in order for them to be binary-safe.
|
||||
Functions that change strings and obtain their new lengths while
|
||||
doing so, should return that new length, so it doesn't have to be
|
||||
recalculated with strlen() (e.g. php_addslashes())
|
||||
recalculated with strlen() (e.g. _php3_addslashes())
|
||||
|
||||
[5] Use php_error() to report any errors/warnings during code execution.
|
||||
[5] Use php3_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,
|
||||
@@ -60,74 +59,28 @@ Exceptions:
|
||||
check its man page again, and only then, consider using it, and even then,
|
||||
try avoiding it.
|
||||
|
||||
[7] Use ZEND_* macros instead of PHP_* macros. Use of PHP_* macros is not
|
||||
recommended. Since most of the PHP_* macros are ZEND_* macro aliases, using
|
||||
the PHP_* macros makes browsing the source code with a tag search harder.
|
||||
|
||||
[8] Use assert(). assert.h is included in php.h if it is available. Not only
|
||||
does good assertion catch bugs, but it also helps with code readability.
|
||||
- Do not use assert for error handling. Use assert only for the
|
||||
condition that must be always true.
|
||||
- Do not use assignments in assert conditions. If you assign inside an
|
||||
assert condition, you risk an elusive bug that would be very difficult
|
||||
to spot in a debug build, due to the side effect of the assignment.
|
||||
Function calls in assert conditions may also cause this problem, if
|
||||
they modify one of their arguments or global variables.
|
||||
|
||||
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 implementation should be prefixed with
|
||||
"php3_", and followed by a word or an underscore-delimited list of words,
|
||||
in lowercase letters, that describes the function.
|
||||
|
||||
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
|
||||
with "_php_", and followed by a word or an underscore-delimited list of
|
||||
[2] Function names used by user functions implementations should be prefixed
|
||||
with "_php3_", 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.
|
||||
|
||||
|
||||
|
||||
Syntax and indentation
|
||||
----------------------
|
||||
|
||||
@@ -141,34 +94,25 @@ Syntax and indentation
|
||||
is known to accept C++-style comments in C code.
|
||||
|
||||
[2] Use K&R-style. Of course, we can't and don't want to
|
||||
force anybody to use a style he or she is not used to, but,
|
||||
force anybody to use a style she's not used to, but
|
||||
at the very least, when you write code that goes into the core
|
||||
of PHP or one of its standard modules, please maintain the K&R
|
||||
style. This applies to just about everything, starting with
|
||||
indentation and comment styles and up to function declaration
|
||||
indentation and comment styles and up to function decleration
|
||||
syntax.
|
||||
|
||||
(see also http://www.tuxedo.org/~esr/jargon/html/entry/indent-style.html)
|
||||
|
||||
[3] Be generous with whitespace and braces. Always prefer:
|
||||
|
||||
if (foo) {
|
||||
[3] Be generous with whitespace and braces. Always prefer
|
||||
if (foo) {
|
||||
bar;
|
||||
}
|
||||
|
||||
to:
|
||||
|
||||
to
|
||||
if(foo)bar;
|
||||
|
||||
Keep one empty line between the variable declaration section and
|
||||
|
||||
Keep one empty line between the variable decleration section and
|
||||
the statements in a block, as well as between logical statement
|
||||
groups in a block. Maintain at least one empty line between
|
||||
two functions, preferably two.
|
||||
|
||||
[4] When indenting, use the tab character. A tab is expected to represent
|
||||
four spaces. It is important to maintain consistency in indenture so
|
||||
that definitions, comments, and control structures line up correctly.
|
||||
|
||||
Documentation and Folding Hooks
|
||||
-------------------------------
|
||||
|
||||
@@ -178,18 +122,18 @@ 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 */
|
||||
PHP_FUNCTION(abs)
|
||||
{
|
||||
Return the absolute value of the number */
|
||||
void php3_abs(INTERNAL_FUNCTION_PARAMETERS) {
|
||||
...
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
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
|
||||
@@ -199,35 +143,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.
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@@ -1,2 +1,176 @@
|
||||
For the list of people who've put work into PHP, please see
|
||||
http://www.php.net/credits.php
|
||||
PHP Version 3.0 Development Team
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Core Developers
|
||||
===============
|
||||
|
||||
Rasmus Lerdorf (rasmus@lerdorf.on.ca)
|
||||
|
||||
* Original language definition and implementation
|
||||
* CGI loader and many internal functions
|
||||
* Apache module support
|
||||
* SNMP module
|
||||
* Original mSQL, MySQL and Sybase modules
|
||||
* Oracle module work
|
||||
|
||||
|
||||
Andi Gutmans (andi@php.net) and Zeev Suraski (zeev@php.net)
|
||||
|
||||
* New language definition and implementation
|
||||
* Internal functions API design
|
||||
* General hash table implementation for symbol tables, arrays and objects
|
||||
* Memory manager
|
||||
* Token cache manager
|
||||
* A lot of internal functions (including hebrev :) and migration from PHP 2.0
|
||||
* Syntax highlighting mode
|
||||
* Configuration file parser
|
||||
* New persistent/multilink MySQL, PosgresSQL, Sybase and mSQL modules
|
||||
* Win32 COM support
|
||||
|
||||
|
||||
Stig Bakken (ssb@guardian.no)
|
||||
|
||||
* Oracle support
|
||||
* configure/install script work
|
||||
* sprintf reimplementation
|
||||
* XML support
|
||||
* SGML documentation framework
|
||||
|
||||
|
||||
Shane Caraveo (shane@caraveo.com)
|
||||
|
||||
* Porting to Visual C++
|
||||
* Generalization to support different server APIs
|
||||
* Work on ISAPI and NSAPI APIs
|
||||
|
||||
|
||||
Jim Winstead (jimw@php.net)
|
||||
|
||||
* Lots of PHP2 -> PHP3 porting
|
||||
* dBase support
|
||||
* URL parsing functions
|
||||
* Makefile work
|
||||
* Regex rewrite
|
||||
* Win32 work
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Major Contributors
|
||||
==================
|
||||
|
||||
* Jouni Ahto (jah@cultnet.fi)
|
||||
Postgres, Informix
|
||||
|
||||
* Alex Belits (abelits@phobos.illtel.denver.co.us)
|
||||
fhttpd support
|
||||
|
||||
* Bjørn Borud (borud@guardian.no)
|
||||
soundex code and lots of enthusiasm
|
||||
|
||||
* Christian Cartus (chc@idgruppe.de)
|
||||
Informix Universal Server support
|
||||
|
||||
* John Ellson (ellson@lucent.com)
|
||||
Freetype support
|
||||
|
||||
* Dean Gaudet (dgaudet@arctic.org)
|
||||
Apache module debugging + helpful hints along the way
|
||||
|
||||
* Mitch Golden (mgolden@interport.net)
|
||||
Oracle testing and bug fixes
|
||||
|
||||
* Danny Heijl (Danny.Heijl@cevi.be)
|
||||
Informix SE support
|
||||
|
||||
* Mark Henderson (mark@togglemedia.com)
|
||||
Various odds and ends
|
||||
|
||||
* Jaakko Hyvätti (jaakko@hyvatti.iki.fi)
|
||||
Prototype cop, regular expression code fixes, CGI security issues
|
||||
|
||||
* Amitay Isaacs (amitay@w-o-i.com)
|
||||
LDAP
|
||||
|
||||
* Andreas Karajannis (Andreas.Karajannis@gmd.de)
|
||||
Adabas D, ODBC, Oracle
|
||||
|
||||
* Igor Kovalenko (owl@infomarket.ru)
|
||||
QNX support issues
|
||||
|
||||
* Richard Lynch (lynch@lscorp.com)
|
||||
Documentation
|
||||
|
||||
* Tom May (tom@go2net.com)
|
||||
Sybase-CT work
|
||||
|
||||
* Muhammad A Muquit (MA_Muquit@fccc.ed)
|
||||
Original Sybase module
|
||||
|
||||
* Mark Musone (musone@edgeglobal.com)
|
||||
IMAP
|
||||
|
||||
* Jeroen van der Most (jvdmost@digiface.nl)
|
||||
Solid
|
||||
|
||||
* Chad Robinson (chadr@brttech.com)
|
||||
Documentation, FilePro
|
||||
|
||||
* Lachlan Roche (lr@www.wwi.com.au)
|
||||
MD5
|
||||
|
||||
* Stefan Roehrich (sr@linux.de)
|
||||
zlib
|
||||
|
||||
* Nikolay P. Romanyuk (mag@redcom.ru)
|
||||
Velocis support
|
||||
|
||||
* Brian Schaffner (brian@tool.net)
|
||||
ODBC support, PHP3 API testing
|
||||
|
||||
* Egon Schmid (eschmid@delos.lf.net)
|
||||
Documentation
|
||||
|
||||
* (sopwith@redhat.com)
|
||||
Solid
|
||||
|
||||
* Colin Viebrock (cmv@privateworld.com)
|
||||
Website graphic design and layout, PHP logo
|
||||
|
||||
* Eric Warnke (ericw@albany.edu)
|
||||
LDAP
|
||||
|
||||
* Lars Torben Wilson (torben@netmill.com)
|
||||
Documentation
|
||||
|
||||
* Uwe Steinmann (Uwe.Steinmann@fernuni-hagen.de)
|
||||
Hyperwave, PDF, Acrobat FDF Toolkit
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Beta Testers
|
||||
------------
|
||||
|
||||
* Niklas Saers (berenmls@saers.com)
|
||||
FreeBSD/x86
|
||||
|
||||
* Chuck Hagenbuch <chuck@osmos.ml.org>
|
||||
Linux/x86 glibc2, MySQL, mod_ssl
|
||||
|
||||
* Sascha Schumann (sas@schell.de)
|
||||
FreeBSD/x86, PostgreSQL, IMAP, gdttf
|
||||
|
||||
* Jim Jagielski (jim@jagunet.com)
|
||||
A/UX, FreeBSD/x86
|
||||
|
||||
* Jouni Ahto (jah@cultnet.fi)
|
||||
Debian Linux 2.0
|
||||
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Andi Gutmans and Zeev Suraski would like to thank Professor Michael Rodeh for
|
||||
his positive input during the initial development of the interpreter.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
-473
@@ -1,473 +0,0 @@
|
||||
List of PHP maintainers
|
||||
=======================
|
||||
|
||||
Maintenance legend
|
||||
------------------
|
||||
Supported: Someone is actually paid to look after this.
|
||||
Maintained: Someone actually looks after it.
|
||||
Odd Fixes: It has a maintainer but they don't have time to do
|
||||
much other than throw the odd patch in. See below.
|
||||
Orphan: No current maintainer [but maybe you could take the
|
||||
role as you write your new code].
|
||||
Obsolete: Old code. Something tagged obsolete generally means
|
||||
it has been replaced by a better system and you
|
||||
should be using that.
|
||||
Unknown: Not known at this time.
|
||||
|
||||
Status legend
|
||||
-------------
|
||||
Working: Working under both Windows and Unix.
|
||||
Windows: Working only under Windows.
|
||||
Unix: Working only under Unix.
|
||||
Experimental: Under development or initial release.
|
||||
Not Working: Not working.
|
||||
Unknown: Status unknown.
|
||||
|
||||
|
||||
== Server APIs ==
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: aolserver
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: apache2
|
||||
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cgi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: fhttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: isapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: nsapi
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: phttpd
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pi3web
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: roxen
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: servlet
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
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: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dbase
|
||||
PRIMARY MAINTAINER: Jim Winstead <jimw@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: dbx
|
||||
PRIMARY MAINTAINER: Marc Boeren <M.Boeren@guidance.nl>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.6
|
||||
COMMENT: DB abstraction for odbc, mysql, pgsql, mssql, fbsql and more, see documentation
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: filepro
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
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
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ingres_ii
|
||||
PRIMARY MAINTAINER: David Hénot <henot@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: interbase
|
||||
PRIMARY MAINTAINER: Jouni Ahto <jouni.ahto@exdec.fi>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msql
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: msession
|
||||
PRIMARY MAINTAINER Mark L. Woodward mlwmohawk@mohawksoft.com
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working/Experimental
|
||||
COMMENT: Tested on Linux, should work on other UNIX platforms. Backend server code can compile under Windows.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mssql
|
||||
PRIMARY MAINTAINER: Frank M. Kromann <fmk@swwwing.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Tested on phpts and isapi versions
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mysql
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pgsql
|
||||
PRIMARY MAINTAINER: Yasuo Ohgaki <yohgaki@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Use PostgreSQL 7.0.x or later. PostgreSQL 6.5.3 or less have fatal bug.
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sybase
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Not Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sybase_ct
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working except for persistent connections
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oracle
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
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: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: calendar
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: com
|
||||
PRIMARY MAINTAINER: Harald Radi <h.radi@nme.at>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: cpdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: crack
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ctype
|
||||
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: curl
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
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: fdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ftp
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gd
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gettext
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: gmp
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: icap
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Obsolete
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: imap
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: java
|
||||
PRIMARY MAINTAINER: Sam Ruby <rubys@us.ibm.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: ldap
|
||||
PRIMARY MAINTAINER: Stig Venaas <venaas@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mbstring
|
||||
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcal
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mcrypt
|
||||
PRIMARY MAINTAINER: Derick Rethans <d.rethans@jdimedia.nl>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: mhash
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: muscat
|
||||
PRIMARY MAINTAINER: Sam Liddicott <sam@ananova.com>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.5
|
||||
COMMENT: Not tested against windows, only core API completed, rest under development
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: openssl
|
||||
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: overload
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pcre
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdf
|
||||
PRIMARY MAINTAINER: Uwe Steinmann <steinm@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pfpro
|
||||
PRIMARY MAINTAINER: David Croft <david@infotrek.co.uk>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: posix
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: printer
|
||||
PRIMARY MAINTAINER: Daniel Beulshausen <daniel@php4win.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 4.0.4
|
||||
COMMENT: Only for Win32
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pspell
|
||||
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com>
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: qtdom
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.4
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: readline
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: recode
|
||||
PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sablot
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Obsolete
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: satellite
|
||||
PRIMARY MAINTAINER: David Eriksson <eriksson@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: session
|
||||
PRIMARY MAINTAINER: Sascha Schumann <sascha@schumann.cx>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: shmop
|
||||
PRIMARY MAINTAINER: Ilia Alshanetsky <iliaa@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: snmp
|
||||
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
|
||||
MAINTENANCE: Odd Fixes
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sockets
|
||||
PRIMARY MAINTAINER: Chris Vandomelen <chrisv@b0rked.dhs.org>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: swf
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Depreciated (Use the ming swf extension instead)
|
||||
COMMENT: Only for Unix (won't change)
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvsem
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Unknown
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: sysvshm
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: vpopmail
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: wddx
|
||||
PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xml
|
||||
PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: xslt
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANC: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
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
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zziplib
|
||||
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Experimental
|
||||
SINCE: 4.0.5
|
||||
-------------------------------------------------------------------------------
|
||||
# iptc?
|
||||
@@ -0,0 +1,54 @@
|
||||
The core of PHP 3.0 is considered to be stable at this time. However, some of
|
||||
the modules that are bundled with it are still undergoing development, or
|
||||
contain known bugs. The purpose of this file is to document the status of
|
||||
each module (extension). Patches to unstable modules will be available through
|
||||
the CVS, and through periodic maintenance releases.
|
||||
|
||||
Stability scale:
|
||||
Rock solid - We believe it's safe to base a production site on it.
|
||||
Stable - It should be safe to base a production site on it.
|
||||
Isn't rated as rock-solid because it contained problems
|
||||
in the not-so-far past, or doesn't have enough users
|
||||
to test it to know it's rock solid.
|
||||
Beta - This module probably contains bugs, sometimes even known
|
||||
bugs. You can give it a try and there's a good chance
|
||||
it'll work fine, but it might not be a good idea to base
|
||||
a production site on it.
|
||||
Alpha - This module is in initial development steps. Don't trust
|
||||
it, play with it at your own risk.
|
||||
Deprecated - This module is only available for downwards compatability,
|
||||
and will not be supported in any way. The code quality
|
||||
is usually around the Beta status.
|
||||
|
||||
The standard disclaimers apply, that is, if a rock-solid module blows up on
|
||||
you and ruins your site, nobody in the PHP development team is responsible.
|
||||
We'll probably try to help, though.
|
||||
|
||||
|
||||
Extension Name Status Comments
|
||||
-----------------------------------------------------------------------------
|
||||
DBM Rock Solid That relies on a working DBM library.
|
||||
The flatfile support is probably not
|
||||
as stable.
|
||||
MySQL Rock Solid
|
||||
mSQL Rock Solid
|
||||
Sybase DB Stable
|
||||
Sybase CT Stable
|
||||
BC Math Rock Solid Arbitary precision math library
|
||||
Postgres SQL Stable Postgres 6.2 and earlier is stable,
|
||||
but problems were reported with 6.3
|
||||
Debugger Beta
|
||||
Unified ODBC Beta
|
||||
Solid Deprecated Replaced by Unified ODBC
|
||||
iODBC Deprecated Replaced by Unified ODBC
|
||||
Adabas Deprecated Replaced by Unified ODBC
|
||||
LDAP Stable Lightweight Directory Access Protocol.
|
||||
dBase
|
||||
FilePro
|
||||
Oracle Beta Not tested thoroughly enough.
|
||||
IMAP Beta Bundled in the dl/ directory
|
||||
SNMP Stable Very solid, but also very limited.
|
||||
Only supports GET and WALK requests.
|
||||
Raima Velocis Beta If use with Unified ODBC, replaced
|
||||
by Unified ODBC
|
||||
Raima Velocis Alpha If use without Unified ODBC
|
||||
@@ -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,189 +1,57 @@
|
||||
Installation Instructions for PHP 4
|
||||
-----------------------------------
|
||||
Installation Instructions for PHP3
|
||||
----------------------------------
|
||||
|
||||
STOP!
|
||||
|
||||
Before going any further, please remember you are going to find more
|
||||
up to date instructions in the online manual, located here:
|
||||
|
||||
http://www.php.net/manual/en/install.apache.php
|
||||
|
||||
It is strongly recommended that you read the manual page before going
|
||||
further. However, for the impatient, here is a quick set of steps that
|
||||
will build PHP as (first) a dynamic Apache module (DSO) for Apache 1.3.x
|
||||
with MySQL support and then a static module. A more verbose explanation follows.
|
||||
|
||||
For installing PHP on other web servers, refer to one of the following
|
||||
files:
|
||||
|
||||
sapi/aolserver/README
|
||||
sapi/pi3web/README
|
||||
sapi/servlet/README
|
||||
sapi/thttpd/README
|
||||
README.Zeus
|
||||
|
||||
Some notes:
|
||||
|
||||
1: Only install either the static module or the dynamic one. Do not
|
||||
install both.
|
||||
|
||||
2: If you are recompiling PHP to add new extensions or upgrading
|
||||
something like GD, remove the config.cache file before you re-run
|
||||
configure.
|
||||
|
||||
3: If you are on Linux and have installed shared libraries, make
|
||||
sure the location of these shared libraries are listed in your
|
||||
/etc/ld.so.conf file. For example, if you have:
|
||||
|
||||
/usr/local/lib/mysql/libmysqlclient.so
|
||||
|
||||
Make sure /etc/ld.so.conf contains:
|
||||
|
||||
/usr/local/lib/mysql
|
||||
|
||||
Then run ldconfig.
|
||||
|
||||
If you want both PHP 3 and 4 modules in the same Apache server, check the
|
||||
bottom of this file for instructions.
|
||||
|
||||
INSTALLATION WITH THE ZEUS WEB SERVER:
|
||||
--Please see the 'README.Zeus' file included in this distribution
|
||||
For the impatient here is a quick set of steps that will build PHP3
|
||||
as an Apache module for Apache 1.3.0 with MySQL support. A more verbose
|
||||
explanation follows.
|
||||
|
||||
|
||||
QUICK INSTALL (DSO)
|
||||
QUICK INSTALL
|
||||
|
||||
For this to work your Apache httpd must have mod_so enabled.
|
||||
Check using httpd -l. You should see something like:
|
||||
|
||||
Compiled-in modules:
|
||||
http_core.c
|
||||
mod_so.c
|
||||
|
||||
Chances are you will see a lot more modules than these two. That's ok,
|
||||
as long as mod_so.c shows up you can proceed with the following steps:
|
||||
|
||||
$ gunzip -c php-4.x.y.tar.gz | tar xf -
|
||||
$ cd php-4.x.y
|
||||
$ ./configure --with-mysql --with-apxs
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
If you get an error telling you that the apxs script could not be found,
|
||||
look for it on your system and if you find it, provide the full path to it
|
||||
as: --with-apxs=/path/to/apxs
|
||||
|
||||
Make sure you specify the version of apxs that is actually installed on
|
||||
your system and NOT the one that is in the apache source tarball.
|
||||
|
||||
Next you must copy php.ini-dist to the appropriate place (normally
|
||||
/usr/local/lib/php.ini) and edit it as necessary to set PHP options.
|
||||
|
||||
The only thing left to do is to edit your httpd.conf file and make sure the
|
||||
PHP 4 mime type is there and uncommented. You need a line that looks like
|
||||
this:
|
||||
|
||||
AddType application/x-httpd-php .php
|
||||
|
||||
Then restart your server (apachectl restart) and you should be able to
|
||||
serve up PHP files now. Make a test file called test.php and put some
|
||||
PHP tags in it. Like <?phpinfo()?>, for example.
|
||||
|
||||
|
||||
QUICK INSTALL (Static)
|
||||
|
||||
$ gunzip -c apache_1.3.x.tar.gz | tar xf -
|
||||
$ cd apache_1.3.x
|
||||
$ ./configure
|
||||
$ cd ..
|
||||
|
||||
$ gunzip -c php-4.x.y.tar.gz | tar xf -
|
||||
$ cd php-4.x.y
|
||||
$ ./configure --with-mysql --with-apache=../apache_1.3.x
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
$ cd ../apache_1.3.x
|
||||
$ ./configure --prefix=/www --activate-module=src/modules/php4/libphp4.a
|
||||
(The above line is correct! Yes, we know libphp4.a does not exist at this
|
||||
gunzip apache_1.3.x.tar.gz
|
||||
tar xvf apache_1.3.x.tar
|
||||
gunzip php-3.0.x.tar.gz
|
||||
tar xvf php-3.0.x.tar
|
||||
cd apache_1.3.x
|
||||
./configure --prefix=/www
|
||||
cd ../php-3.0.x
|
||||
./configure --with-mysql --with-apache=../apache_1.3.x --enable-track-vars
|
||||
make
|
||||
make install
|
||||
cd ../apache_1.3.x
|
||||
./configure --prefix=/www --activate-module=src/modules/php3/libphp3.a
|
||||
(The above line is correct! Yes, we know libphp3.a does not exist at this
|
||||
stage. It isn't supposed to. It will be created.)
|
||||
$ make
|
||||
(you should now have an httpd binary which you can copy to your Apache bin dir if
|
||||
is is your first install then you need to "make install" as well)
|
||||
$ cd ../php-4.x.y
|
||||
$ cp php.ini-dist /usr/local/lib/php.ini
|
||||
You can edit /usr/local/lib/php.ini file to set PHP options.
|
||||
make
|
||||
(you should now have an httpd binary which you can copy to your Apache bin dir)
|
||||
cd ../php-3.0.x
|
||||
cp php3.ini-dist /usr/local/lib/php3.ini
|
||||
You can edit /usr/local/lib/php3.ini file to set PHP options.
|
||||
Edit your httpd.conf or srm.conf file and add:
|
||||
AddType application/x-httpd-php .php
|
||||
AddType application/x-httpd-php3 .php3
|
||||
|
||||
|
||||
VERBOSE INSTALL
|
||||
|
||||
Chances are you are reading this because the quick install steps above
|
||||
did not work for you. If this is the case, congratulations, you are
|
||||
among the elite few that actually reads documentation. It really is
|
||||
not a difficult install and once you have done it once you will fly
|
||||
through it.
|
||||
|
||||
Installing PHP can be done in four simple steps:
|
||||
Installing PHP3 can be done in four simple steps:
|
||||
|
||||
1. Unpack your distribution file.
|
||||
|
||||
You will have downloaded a file named something like php-4.x.y.tar.gz.
|
||||
Unzip this file with a command like: gunzip php-4.x.y.tar.gz
|
||||
You will have downloaded a file named something like php3xn.tar.gz.
|
||||
Unzip this file with a command like: gunzip php3xn.tar.gz
|
||||
|
||||
Next you have to untar it with: tar -xvf php-4.x.y.tar
|
||||
Next you have to untar it with: tar -xvf php3xn.tar
|
||||
|
||||
This will create a php-4.x.y directory. cd into this new directory.
|
||||
This will create a php-3.0.x directory. cd into this new directory.
|
||||
|
||||
2a. Configure PHP (Dynamic Module) - Skip to 2b if you wish to build
|
||||
a static module
|
||||
2. Configure PHP3.
|
||||
|
||||
You now have to choose the options you would like. There are quite
|
||||
a few of them. To see a list, type: ./configure --help
|
||||
|
||||
The only options that you are likely to want to use are the ones in
|
||||
the last section entitled, "--enable and --with options recognized:"
|
||||
|
||||
A popular choice is to build the Apache module version. In order to
|
||||
build PHP as a dynamic module for Apache-1.3.x you have to first have
|
||||
Apache installed. Assuming Apache is already installed, make sure
|
||||
the shared object module is enabled. To check this, type: httpd -l
|
||||
You should see something like:
|
||||
|
||||
Compiled-in modules:
|
||||
http_core.c
|
||||
mod_so.c
|
||||
|
||||
You will most likely have a lot more modules than what is shown here.
|
||||
As long as mod_so.c shows up in the list, PHP should be happy.
|
||||
|
||||
Now, type: ./configure --with-mysql --with-apxs
|
||||
|
||||
If you get an error telling you that the apxs script could not be found,
|
||||
look for it on your system and if you find it, provide the full path to it
|
||||
as: --with-apxs=/path/to/apxs
|
||||
|
||||
Make sure you specify the version of apxs that is actually installed on
|
||||
your system and NOT the one that is in the apache source tarball.
|
||||
|
||||
You might also want other flags on this configure line. --with-mysql
|
||||
is just an example.
|
||||
|
||||
There are a few things that can go wrong during this configure step.
|
||||
The most common is that you have asked for an option and that the
|
||||
configure script can not find the files required to enable this
|
||||
option in PHP. Chances are you can provide the full path to the
|
||||
base directory under which the related files were installed. For
|
||||
example, if you have installed the GD library in /opt/gd which means
|
||||
that /opt/gd/include has your GD header files and /opt/gd/lib contains
|
||||
your GD library files, you would use --with-gd=/opt/gd
|
||||
|
||||
Skip to step 3 for compilation and installation instructions.
|
||||
|
||||
2b. Configure PHP (Static Module) - Skip if you performed 2a
|
||||
|
||||
You now have to choose the options you would like. There are quite
|
||||
a few of them. To see a list, type: ./configure --help
|
||||
You can also use the supplied 'setup' script, which will ask you
|
||||
a series of questions and automatically run the configure script
|
||||
for you.
|
||||
|
||||
The only options that you are likely to want to use are the ones in
|
||||
the last section entitled, "--enable and --with options recognized:"
|
||||
@@ -210,18 +78,10 @@ Installing PHP can be done in four simple steps:
|
||||
Apache Configure script at least once before compiling PHP. It
|
||||
doesn't matter how you have Apache configured at this point.
|
||||
|
||||
Skip to step 3b at this point.
|
||||
|
||||
3. Compile and install the files. Simply type: make install
|
||||
|
||||
3a. Dynamic Module Installation
|
||||
|
||||
Nothing else is needed here. Proceed to step 4a.
|
||||
|
||||
3b. Static Module Installation
|
||||
|
||||
For the Apache module version this will copy the appropriate files
|
||||
to the src/modules/php4 directory in your Apache distribution if
|
||||
to the src/modules/php3 directory in your Apache distribution if
|
||||
you are using Apache 1.3.x. If you are still running Apache 1.2.x
|
||||
these files will be copied directly to the main src directory.
|
||||
|
||||
@@ -230,7 +90,7 @@ Installing PHP can be done in four simple steps:
|
||||
|
||||
cd apache_1.3.x
|
||||
./configure --prefix=/<path>/apache \
|
||||
--activate-module=src/modules/php4/libphp4.a
|
||||
--activate-module=src/modules/php3/libphp3.a
|
||||
make
|
||||
make install
|
||||
|
||||
@@ -243,29 +103,29 @@ Installing PHP can be done in four simple steps:
|
||||
|
||||
For Apache 1.3.x add:
|
||||
|
||||
AddModule modules/php4/libphp4.a
|
||||
AddModule modules/php3/libphp3.a
|
||||
|
||||
For Apache 1.3.x don't do anything else. Just add this line and then
|
||||
run "./Configure" followed by "make".
|
||||
|
||||
For Apache 1.2.x add:
|
||||
|
||||
Module php4_module mod_php4.o
|
||||
Module php3_module mod_php3.o
|
||||
|
||||
For Apache 1.2.x you will also have to look in the libphp4.module file,
|
||||
For Apache 1.2.x you will also have to look in the libphp3.module file,
|
||||
which was copied to the src directory. The EXTRA_LIBS line in the Apache
|
||||
Configuration file needs to be set to use the same libs as specified on
|
||||
the LIBS line in libphp4.module. You also need to make sure to add
|
||||
the LIBS line in libphp3.module. You also need to make sure to add
|
||||
"-L." to the beginning of the EXTRA_LIBS line.
|
||||
|
||||
So, as an example, your EXTRA_LIBS line might look like:
|
||||
|
||||
EXTRA_LIBS=-L. -lphp4 -lgdbm -ldb -L/usr/local/mysql/lib -lmysqlclient
|
||||
EXTRA_LIBS=-L. -lphp3 -lgdbm -ldb -L/usr/local/mysql/lib -lmysqlclient
|
||||
|
||||
NOTE: You should not enclose the EXTRA_LIBS line in double-quotes, as it
|
||||
is in the libphp4.module file.
|
||||
is in the libphp3.module file.
|
||||
|
||||
Also, look at the RULE_WANTHSREGEX setting in the libphp4.module file
|
||||
Also, look at the RULE_WANTHSREGEX setting in the libphp3.module file
|
||||
and set the WANTHSREGEX directive accordingly in your Configuration file.
|
||||
This last step applies to versions of Apache prior to 1.3b3.
|
||||
|
||||
@@ -277,141 +137,23 @@ Installing PHP can be done in four simple steps:
|
||||
somewhere. Re-edit Configuration and try again. If it goes well,
|
||||
type: make
|
||||
|
||||
Assuming it compiles without errors, proceed to step 4b.
|
||||
|
||||
4a. Setting up the server. (Dynamic Module)
|
||||
|
||||
The make install command in step 3 should have done most of your
|
||||
work for you. It actually edits your httpd.conf file and tries to
|
||||
enable the dynamic PHP module. To verify this, look for a line that
|
||||
looks like this:
|
||||
|
||||
LoadModule php4_module libexec/libphp4.so
|
||||
|
||||
The actual path before the libphp4.so part might differ slightly. This
|
||||
is likely fine. If you are paranoid you can examine the output from the
|
||||
make install step to see where the libphp4.so file was actually put and
|
||||
place the full path to this file on this LoadModule line.
|
||||
|
||||
If somewhere in your httpd.conf file you have a ClearModuleList line
|
||||
then you also need this line:
|
||||
|
||||
AddModule mod_php4.c
|
||||
|
||||
And finally you need to tell Apache which file extension should trigger
|
||||
PHP. You do this by creating a special mime type and associating it
|
||||
with an extension. We suggest using:
|
||||
|
||||
AddType application/x-httpd-php .php
|
||||
|
||||
You are however free to use any extension you wish, including .html.
|
||||
|
||||
Note! If a line has a # at the beginning, then it is commented out
|
||||
and you need to remove the # for that line to take effect.
|
||||
|
||||
Finally you need to copy php.ini-dist to the appropriate place
|
||||
(normally /usr/local/lib/php.ini) and edit if necessary.
|
||||
|
||||
Once you have made these changes you should be ready to restart your
|
||||
server and try it out. Type: apachectl restart
|
||||
|
||||
4b. Setting up the server. (Static Module)
|
||||
4. Setting up the server.
|
||||
|
||||
You should now have a new httpd binary. Shut down your existing server,
|
||||
if you have one, and copy this new binary overtop of it. Perhaps make
|
||||
a backup of your previous one first. Then edit your conf/httpd.conf file
|
||||
a backup of your previous one first. Then edit your conf/srm.conf file
|
||||
and add the line:
|
||||
|
||||
AddType application/x-httpd-php .php
|
||||
AddType application/x-httpd-php3 .php3
|
||||
|
||||
There is also an interesting feature which can be quite instructive and
|
||||
helpful while debugging. That is the option of having colour syntax
|
||||
highlighting. To enable this, add the following line:
|
||||
|
||||
AddType application/x-httpd-php-source .phps
|
||||
AddType application/x-httpd-php3-source .phps
|
||||
|
||||
Any file ending in .phps will now be displayed with full colour syntax
|
||||
highlighting instead of being executed.
|
||||
|
||||
Note that on some older server setups, the AddType lines are in the
|
||||
conf/srm.conf file instead of conf/httpd.conf.
|
||||
|
||||
Note! If a line has a # at the beginning, then it is commented out
|
||||
and you need to remove the # for that line to take effect.
|
||||
|
||||
When you are finished making changes to your httpd.conf file, you need
|
||||
to copy php.ini-dist to the appropriate place (normally
|
||||
/usr/local/lib/php.ini) and edit if necessary. You can then
|
||||
When you are finished making changes to your srm.conf file, you can
|
||||
start up your server.
|
||||
|
||||
5. Testing it all worked
|
||||
|
||||
Create a test file named test.php in your web tree somewhere and
|
||||
put some test PHP tags in it. <?phpinfo()?> is a good first test.
|
||||
This tag tells PHP to do a braindump and tells you all sorts of things
|
||||
about itself.
|
||||
|
||||
|
||||
WHY DISABLING -fPIC WORKS ON LINUX
|
||||
|
||||
From: Martin v. Loewis <martin@loewis.home.cs.tu-berlin.de>
|
||||
To: glibc-linux@ricardo.ecn.wfu.edu
|
||||
Subject: Re: Shared library -shared vs. -fpic
|
||||
|
||||
[In reply to Kaz Kylheku <kaz@ashi.footprints.net>]
|
||||
|
||||
> PIC stands for Position-Independent Code.
|
||||
|
||||
Correct.
|
||||
|
||||
> Code isn't position-independent (or ``relocatable'') cannot be
|
||||
> loaded at an arbitrary address;
|
||||
|
||||
Wrong.
|
||||
|
||||
> it requires some references to be patched at load time.
|
||||
|
||||
Correct.
|
||||
|
||||
> Shared libraries need to be relocatable because it's not known
|
||||
> beforehand what address they will be loaded at
|
||||
|
||||
Correct, depending on the meaning of "relocatable". PIC code typically
|
||||
does not contain relocations; that's why its position-independent.
|
||||
|
||||
> Just because you don't specify -fPIC doesn't mean that the compiler
|
||||
> won't emit position-independent code; the option prevents it from
|
||||
> emitting position-dependent code in situations where it otherwise
|
||||
> would.
|
||||
|
||||
Correct. However, a non-trivial shared library typically won't be
|
||||
position-independent unless explicitly compiled with
|
||||
-fPIC. Linux/glibc indeed does not require a shared library to be
|
||||
position-independent; instead, it will perform the relocations in the
|
||||
binary, even if they refer to code pages. As a result, those relocated
|
||||
pages won't be shared across processes, anymore.
|
||||
|
||||
Regards,
|
||||
Martin
|
||||
|
||||
USING PHP 3 AND PHP 4 AS CONCURRENT APACHE MODULES
|
||||
|
||||
With some (newer) installations of Apache, it's possible to compile both
|
||||
PHP 3 and PHP 4, and run them concurrently.
|
||||
|
||||
Note, it's only really wise to do this if you need to use the PHP 3 engine
|
||||
to maintain backwards compatibility.
|
||||
|
||||
To enable it, configure PHP 3 and PHP 4 to use APXS (--with-apxs) and the
|
||||
necessary link extensions (--enable-versioning). Otherwise, all standard
|
||||
installations instructions apply. For example:
|
||||
|
||||
$ ./configure \
|
||||
--with-apxs=/apache/bin/apxs \
|
||||
--enable-versioning \
|
||||
--with-mysql \
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,68 +1,64 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.0
|
||||
Copyright (c) 1999 - 2002 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
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.
|
||||
--------------------------------------------------------------------
|
||||
Copyright (c) 1998 The PHP Development Team. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
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"
|
||||
|
||||
5. 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
|
||||
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.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Commercial redistribution of larger works derived from, or
|
||||
works which bundle PHP, requires written permission from the
|
||||
PHP Development Team. You may charge a fee for the physical
|
||||
act of transferring a copy, and must make it clear that the
|
||||
fee being charged is for the distribution, and not for the
|
||||
software itself. You may, at your option, offer warranty
|
||||
protection in exchange for a fee.
|
||||
|
||||
2. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
3. 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.
|
||||
|
||||
4. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software written by the PHP Development
|
||||
Team"
|
||||
|
||||
5. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission
|
||||
from the PHP Development Team. 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.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP, freely available from
|
||||
<http://www.php.net/>".
|
||||
"This product includes software written by the PHP Development
|
||||
Team".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``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 THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS 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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``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 THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS 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.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the PHP Development Team.
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the PHP Group.
|
||||
|
||||
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>.
|
||||
The PHP Development Team can be contacted via Email at core@php.net.
|
||||
|
||||
For more information on the PHP Development Team and the PHP
|
||||
project, please see <http://www.php.net>.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
$(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,74 +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)
|
||||
|
||||
|
||||
all: $(all_targets)
|
||||
|
||||
build-modules: $(PHP_MODULES)
|
||||
|
||||
libphp4.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(LIBTOOL) --mode=link $(CC) $(COMMON_FLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
|
||||
|
||||
libs/libphp4.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp4.so
|
||||
|
||||
php: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
|
||||
$(BUILD_CGI)
|
||||
|
||||
sapi/cli/php: $(PHP_GLOBAL_OBJS) $(PHP_CLI_OBJS)
|
||||
$(BUILD_CLI)
|
||||
|
||||
install: $(install_targets)
|
||||
|
||||
|
||||
install-cli: sapi/cli/php
|
||||
@echo "Installing PHP CLI binary: $(INSTALL_ROOT)$(bindir)/"
|
||||
@$(INSTALL_CLI)
|
||||
|
||||
install-sapi: libphp4.la
|
||||
@echo "Installing PHP SAPI module"
|
||||
-@$(LIBTOOL) --silent --mode=install cp libphp4.la $(phptempdir)/libphp4.la >/dev/null 2>&1
|
||||
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
|
||||
-@if test ! -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); then \
|
||||
for i in 0.0.0 0.0 0; do \
|
||||
if test -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i; then \
|
||||
$(LN_S) $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); \
|
||||
break; \
|
||||
fi; \
|
||||
done; \
|
||||
fi
|
||||
@$(INSTALL_IT)
|
||||
|
||||
install-modules: build-modules
|
||||
@test -d modules && \
|
||||
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR) && \
|
||||
echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/" && \
|
||||
rm -f modules/*.la && \
|
||||
cp modules/* $(INSTALL_ROOT)$(EXTENSION_DIR) >/dev/null 2>&1 || true
|
||||
|
||||
install-tester:
|
||||
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
|
||||
@$(mkinstalldirs) $(PEAR_INSTALLDIR)
|
||||
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
|
||||
|
||||
install-su: install-pear install-tester
|
||||
|
||||
test: sapi/cli/php
|
||||
@TEST_PHP_EXECUTABLE=$(top_builddir)/sapi/cli/php \
|
||||
$(top_builddir)/sapi/cli/php -c php.ini-dist $(top_srcdir)/run-tests.php
|
||||
|
||||
clean:
|
||||
find . -name \*.lo -o -name \*.o -o -name \*.la -o -name \*.a| xargs rm -f
|
||||
find . -name .libs -a -type d|xargs rm -rf
|
||||
rm -f libphp4.la php sapi/cli/php modules/* libs/*
|
||||
|
||||
distclean: clean
|
||||
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php4.spec sapi/apache/libphp4.module buildmk.stamp
|
||||
find . -name Makefile | xargs rm -f
|
||||
|
||||
.PHONY: all clean install distclean test
|
||||
.NOEXPORT:
|
||||
+1078
File diff suppressed because it is too large.
Load diff
@@ -1,115 +0,0 @@
|
||||
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.
|
||||
|
||||
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
|
||||
some basic rules with regards to CVS usage will:
|
||||
|
||||
a. Make everybody happier, especially those responsible for maintaining
|
||||
the CVS itself.
|
||||
b. Keep the changes consistently well documented and easily trackable.
|
||||
c. Prevent some of those 'Oops' moments.
|
||||
d. Increase the general level of good will on planet Earth.
|
||||
|
||||
|
||||
Having said that, here are the organizational rules:
|
||||
|
||||
1. Respect other people working on the project.
|
||||
|
||||
2. Discuss any significant changes on the list before committing.
|
||||
|
||||
3. Look at EXTENSIONS file to see who is the primary maintainer of
|
||||
the code you want to contribute to.
|
||||
|
||||
4. If you "strongly disagree" about something another person did, don't
|
||||
start fighting publicly - take it up in private email.
|
||||
|
||||
5. If you don't know how to do something, ask first!
|
||||
|
||||
6. Test your changes before committing them. We mean it. Really.
|
||||
|
||||
|
||||
The next few rules are more of a technical nature.
|
||||
|
||||
1. DO NOT TOUCH ChangeLog! It is automagically updated from the commit
|
||||
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. 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
|
||||
provide a nice commit message for each one. See example below.
|
||||
|
||||
4. Do write your commit message in such a way that it makes sense even
|
||||
without the corresponding diff. One should be able to look at it, and
|
||||
immediately know what was modified. Definitely include the function name
|
||||
in the message as shown below.
|
||||
|
||||
5. In your commit messages, keep each line shorter than 80 characters. And
|
||||
try to align your lines vertically, if they wrap. It looks bad otherwise.
|
||||
|
||||
6. If you modified a function that is callable from PHP, prepend PHP to
|
||||
the function name as shown below.
|
||||
|
||||
|
||||
The format of the commit messages is pretty simple.
|
||||
|
||||
If a line begins with #, it is taken to be a comment and will not appear
|
||||
in the ChangeLog. 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 # 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. Your name WILL NOT be automatically put
|
||||
at the end of the NEWS entry - so, please provide it yourself.
|
||||
|
||||
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:
|
||||
|
||||
(PHP date) Added new 'K' format modifier for printing out number of
|
||||
days until New Year's Eve.
|
||||
@- Added new 'K' format modifier that will output the number of days
|
||||
@ until New Year's Eve. (Bob)
|
||||
|
||||
For string.c:
|
||||
(php_trim) Fixed a memory leak resulting from improper use of zval_dtor().
|
||||
# Man, that thing was leaking all over the place!
|
||||
@- Fixed memory leak in trim(). (Bob)
|
||||
|
||||
The lines above marked with @ will go into NEWS file automagically, and the
|
||||
# lines will be omitted from the ChangeLog. Alternatively, you might want
|
||||
to modify NEWS file directly and not use the @ lines.
|
||||
|
||||
If you fix some bugs, you should note the bug ID numbers in your
|
||||
commit message. Bug ID should be prefixed by "#" for easier access to
|
||||
bug report when developers are browsing CVS via. LXR or Bonsai.
|
||||
|
||||
Example:
|
||||
|
||||
Fixed pgsql notice handler double free crash bug. Bug #14016
|
||||
@ Fixed pgsql notice handler double free crash bug. Bug #14016
|
||||
|
||||
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. 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.
|
||||
|
||||
To receive daily updates to ChangeLog and NEWS, send an empty message to
|
||||
php-cvs-daily-subscribe@lists.php.net.
|
||||
|
||||
Happy hacking,
|
||||
|
||||
PHP Team
|
||||
@@ -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.
|
||||
-189
@@ -1,189 +0,0 @@
|
||||
|
||||
WHAT IT IS
|
||||
|
||||
It's a tool for automatically creating the basic framework for a PHP module
|
||||
and writing C code handling arguments passed to your functions from a simple
|
||||
configuration file. See an example at the end of this file.
|
||||
|
||||
HOW TO USE IT
|
||||
|
||||
Very simple. First, cd do directory ext/ in PHP 4 sources. If you just need
|
||||
the basic framework and will be writing all the code in your functions
|
||||
yourself, you can now do
|
||||
|
||||
./ext_skel --extname=module_name
|
||||
|
||||
and everything you need is placed in directory module_name.
|
||||
|
||||
[ Note that GNU awk is likely required for this script to work. Debian
|
||||
systems seem to default to using mawk, so you may need to change the
|
||||
#! line in skeleton/create_stubs to use gawk explicitly. ]
|
||||
|
||||
If you don't need to test the existence of any external header files,
|
||||
libraries or functions in them, the module is already almost ready to be
|
||||
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
|
||||
cd back up to PHP sources top directory, and do
|
||||
|
||||
./buildconf; ./configure --enable-module_name; make
|
||||
|
||||
But if you already have planned the overall scheme of your module, what
|
||||
functions it will contain, their return types and the arguments they take
|
||||
(a very good idea) and don't want to bother yourself with creating function
|
||||
definitions and handling arguments passed yourself, it's time to create a
|
||||
function definitions file, which you will give as an argument to ext_skel
|
||||
with option
|
||||
|
||||
--proto=filename.
|
||||
|
||||
FORMAT OF FUNCTION DEFINITIONS FILE
|
||||
|
||||
All the definitions must be on one line. In it's simplest form, it's just
|
||||
the function name, ie.
|
||||
|
||||
my_function
|
||||
|
||||
but then you'll be left with an almost empty function body without any
|
||||
argument handling.
|
||||
|
||||
Arguments are given in parenthesis after the function name, and are of
|
||||
the form 'argument_type argument_name'. Arguments are separated from each
|
||||
other with a comma and optional space. Argument_type can be one of int,
|
||||
bool, double, float, string, array, object or mixed.
|
||||
|
||||
An optional argument is separated from the previous by an optional space,
|
||||
then '[' and of course comma and optional space, like all the other
|
||||
arguments. You should close a row of optional arguments with same amount of
|
||||
']'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
|
||||
|
||||
Arguments arg3 and arg4 are optional.
|
||||
|
||||
If possible, the function definition should also contain it's return type
|
||||
in front of the definition. It's not actually used for any C code generating
|
||||
purposes but PHP in-source documentation instead, and as such, very useful.
|
||||
It can be any of int, double, string, bool, array, object, resource, mixed
|
||||
or void.
|
||||
|
||||
The file must contain nothing else but function definitions, no comments or
|
||||
empty lines.
|
||||
|
||||
OTHER OPTIONS
|
||||
|
||||
--no-help
|
||||
|
||||
By default, ext_skel creates both comments in the source code and a test
|
||||
function to help first time module writers to get started and testing
|
||||
configuring and compiling their module. This option turns off all such things
|
||||
which may just annoy experienced PHP module coders. Especially useful with
|
||||
|
||||
--stubs=file
|
||||
|
||||
which will leave out also all module specific stuff and write just function
|
||||
stubs with function value declarations and passed argument handling, and
|
||||
function entries and definitions at the end of the file, for copying and
|
||||
pasting into an already existing module.
|
||||
|
||||
--assign-params
|
||||
--string-lens
|
||||
|
||||
By default, function proto 'void foo(string bar)' creates the following:
|
||||
...
|
||||
zval **bar;
|
||||
... (zend_get_parameters_ex() called in the middle...)
|
||||
convert_to_string_ex(bar);
|
||||
|
||||
Specifying both of these options changes the generated code to:
|
||||
...
|
||||
zval **bar_arg;
|
||||
int bar_len;
|
||||
char *bar = NULL;
|
||||
... (zend_get_parameters_ex() called in the middle...)
|
||||
convert_to_string_ex(bar_arg);
|
||||
bar = Z_STRVAL_PP(bar_arg);
|
||||
bar_len = Z_STRLEN_PP(bar_arg);
|
||||
|
||||
You shouldn't have to ask what happens if you leave --string-lens out. If you
|
||||
have to, it's questionable whether you should be reading this document.
|
||||
|
||||
--with-xml[=file]
|
||||
|
||||
Creates the basics for phpdoc .xml file.
|
||||
|
||||
--full-xml
|
||||
|
||||
Not implemented yet. When or if there will ever be created a framework for
|
||||
self-contained extensions to use phpdoc system for their documentation, this
|
||||
option enables it on the created xml file.
|
||||
|
||||
CURRENT LIMITATIONS, BUGS AND OTHER ODDITIES
|
||||
|
||||
Only arguments of types int, bool, double, float, string and array are
|
||||
handled. For other types you must write the code yourself. And for type
|
||||
mixed, it wouldn't even be possible to write anything, because only you
|
||||
know what to expect.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
This program doesn't have a --help option. It has --no-help instead.
|
||||
|
||||
EXAMPLE
|
||||
|
||||
The following _one_ line
|
||||
|
||||
bool my_drawtext(resource image, string text, resource font, int x, int y [, int color])
|
||||
|
||||
will create this function definition for you (note that there are a few
|
||||
question marks to be replaced by you, and you must of course add your own
|
||||
value definitions too):
|
||||
|
||||
/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y[, int color])
|
||||
*/
|
||||
PHP_FUNCTION(my_drawtext)
|
||||
{
|
||||
zval **image, **text, **font, **x, **y, **color;
|
||||
int argc;
|
||||
int image_id = -1;
|
||||
int font_id = -1;
|
||||
|
||||
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);
|
||||
|
||||
switch (argc) {
|
||||
case 6:
|
||||
convert_to_long_ex(color);
|
||||
/* Fall-through. */
|
||||
case 5:
|
||||
convert_to_long_ex(y);
|
||||
convert_to_long_ex(x);
|
||||
/* font: fetching resources already handled. */
|
||||
convert_to_string_ex(text);
|
||||
/* image: fetching resources already handled. */
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
}
|
||||
|
||||
php_error(E_WARNING, "my_drawtext: not yet implemented");
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -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 autoconverted.
|
||||
|
||||
|
||||
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,154 +0,0 @@
|
||||
$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, three things are
|
||||
required:
|
||||
|
||||
- Configuration file (config.m4)
|
||||
- Source code for your module
|
||||
|
||||
We will describe now how to create these and how to put things
|
||||
together.
|
||||
|
||||
PREPARING YOUR SYSTEM
|
||||
|
||||
While the result will run on any system, a developer's setup needs these
|
||||
tools:
|
||||
|
||||
GNU autoconf
|
||||
GNU automake
|
||||
GNU libtool
|
||||
GNU m4
|
||||
|
||||
All of these are available from
|
||||
|
||||
ftp://ftp.gnu.org/pub/gnu/
|
||||
|
||||
CONVERTING AN EXISTING EXTENSION
|
||||
|
||||
Just to show you how easy it is to create a self-contained
|
||||
extension, we will convert an embedded extension into a
|
||||
self-contained one. Install PHP and execute the following
|
||||
commands.
|
||||
|
||||
$ mkdir /tmp/newext
|
||||
$ cd /tmp/newext
|
||||
|
||||
You now have an empty directory. We will copy the files from
|
||||
the mysql extension:
|
||||
|
||||
$ cp -rp php-4.0.X/ext/mysql/* .
|
||||
|
||||
It is time to finish the module. Run:
|
||||
|
||||
$ phpize
|
||||
|
||||
You can now ship the contents of the directory - the extension
|
||||
can live completely on its own.
|
||||
|
||||
The user instructions boil down to
|
||||
|
||||
$ ./configure \
|
||||
[--with-php-config=/path/to/php-config] \
|
||||
[--with-mysql=MYSQL-DIR]
|
||||
$ make install
|
||||
|
||||
The MySQL module will either use the embedded MySQL client
|
||||
library or the MySQL installation in MYSQL-DIR.
|
||||
|
||||
|
||||
DEFINING THE NEW EXTENSION
|
||||
|
||||
Our demo extension is called "foobar".
|
||||
|
||||
It consists of two source files "foo.c" and "bar.c"
|
||||
(and any arbitrary amount of header files, but that is not
|
||||
important here).
|
||||
|
||||
The demo extension does not reference any external
|
||||
libraries (that is important, because the user does not
|
||||
need to specify anything).
|
||||
|
||||
|
||||
LTLIBRARY_SOURCES specifies the names of the sources files. You can
|
||||
name an arbitrary number of source files here.
|
||||
|
||||
CREATING THE M4 CONFIGURATION FILE
|
||||
|
||||
The m4 configuration can perform additional checks. For a
|
||||
self-contained extension, you do not need more than a few
|
||||
macro calls.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
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)
|
||||
fi
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
PHP_ARG_ENABLE will automatically set the correct variables, so
|
||||
that the extension will be enabled by PHP_NEW_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.
|
||||
|
||||
CREATING SOURCE FILES
|
||||
|
||||
ext_skel can be of great help when creating the common code for all modules
|
||||
in PHP for you and also writing basic function definitions and C code for
|
||||
handling arguments passed to your functions. See README.EXT_SKEL for further
|
||||
information.
|
||||
|
||||
As for the rest, you are currently alone here. There are a lot of existing
|
||||
modules, use a simple module as a starting point and add your own code.
|
||||
|
||||
|
||||
CREATING THE SELF-CONTAINED EXTENSION
|
||||
|
||||
Put config.m4 and the source files into one directory. Afterwards,
|
||||
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
|
||||
|
||||
This will automatically copy the necessary build files and create
|
||||
configure from your config.m4.
|
||||
|
||||
And that's it. You now have a self-contained extension.
|
||||
|
||||
INSTALLING A SELF-CONTAINED EXTENSION
|
||||
|
||||
An extension can be installed by running:
|
||||
|
||||
$ ./configure \
|
||||
[--with-php-config=/path/to/php-config]
|
||||
$ make install
|
||||
|
||||
ADDING SHARED MODULE SUPPORT TO A MODULE
|
||||
|
||||
In order to be useful, a self-contained extension must be loadable
|
||||
as a shared module. I will explain now how you can add shared 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[,..].
|
||||
|
||||
2. In config.m4, use PHP_NEW_EXTENSION(foo,.., $ext_shared) to enable
|
||||
building the extension.
|
||||
|
||||
3. Add the following lines to your C source file:
|
||||
|
||||
#ifdef COMPILE_DL_FOO
|
||||
ZEND_GET_MODULE(foo)
|
||||
#endif
|
||||
-367
@@ -1,367 +0,0 @@
|
||||
An Overview of the PHP Streams abstraction
|
||||
==========================================
|
||||
$Id$
|
||||
|
||||
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 everytime 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 int php_stream_eof(php_stream * stream);
|
||||
PHPAPI int php_stream_getc(php_stream * stream);
|
||||
PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
|
||||
PHPAPI int php_stream_close(php_stream * stream);
|
||||
PHPAPI int php_stream_flush(php_stream * stream);
|
||||
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
|
||||
PHPAPI off_t php_stream_tell(php_stream * stream);
|
||||
|
||||
These (should) behave in the same way as the ANSI stdio functions with similar
|
||||
names: fread, fwrite, feof, fgetc, fgets, fclose, fflush, fseek, ftell.
|
||||
|
||||
Opening Streams
|
||||
===============
|
||||
In most cases, you should use this API:
|
||||
|
||||
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
|
||||
int options, char **opened_path TSRMLS_DC);
|
||||
|
||||
Where:
|
||||
path is the file or resource to open.
|
||||
mode is the stdio compatible mode eg: "wb", "rb" etc.
|
||||
options is a combination of the following values:
|
||||
IGNORE_PATH (default) - don't use include path to search for the file
|
||||
USE_PATH - use include path to search for the file
|
||||
IGNORE_URL - do not use plugin wrappers
|
||||
REPORT_ERRORS - show errors in a standard format if something
|
||||
goes wrong.
|
||||
STREAM_MUST_SEEK - If you really need to be able to seek the stream
|
||||
and don't need to be able to write to the original
|
||||
file/URL, use this option to arrange for the stream
|
||||
to be copied (if needed) into a stream that can
|
||||
be seek()ed.
|
||||
|
||||
opened_path is used to return the path of the actual file opened,
|
||||
but if you used STREAM_MUST_SEEK, may not be valid. You are
|
||||
responsible for efree()ing opened_path. opened_path may be (and usually
|
||||
is) NULL.
|
||||
|
||||
If you need to open a specific stream, or convert standard resources into
|
||||
streams there are a range of functions to do this defined in php_streams.h.
|
||||
A brief list of the most commonly used functions:
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
|
||||
Convert a FILE * into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
|
||||
Open a FILE * with tmpfile() and convert into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
|
||||
const char *pfx, char **opened_path TSRMLS_DC);
|
||||
Generate a temporary file name and open it.
|
||||
|
||||
There are some network enabled relatives in php_network.h:
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
|
||||
Convert a socket into a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
|
||||
int socktype, int timeout, int persistent);
|
||||
Open a connection to a host and return a stream.
|
||||
|
||||
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
|
||||
struct timeval *timeout);
|
||||
Open a UNIX domain socket.
|
||||
|
||||
|
||||
Stream Utilities
|
||||
================
|
||||
|
||||
If you need to copy some data from one stream to another, you will be please
|
||||
to know that the streams API provides a standard way to do this:
|
||||
|
||||
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
|
||||
php_stream *dest, size_t maxlen);
|
||||
|
||||
If you want to copy all remaining data from the src stream, pass
|
||||
PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
|
||||
number of bytes to copy.
|
||||
This function will try to use mmap where available to make the copying more
|
||||
efficient.
|
||||
|
||||
If you want to read the contents of a stream into an allocated memory buffer,
|
||||
you should use:
|
||||
|
||||
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
|
||||
size_t maxlen, int persistent);
|
||||
|
||||
This function will set buf to the address of the buffer that it allocated,
|
||||
which will be maxlen bytes in length, or will be the entire length of the
|
||||
data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
|
||||
The buffer is allocated using pemalloc(); you need to call pefree() to
|
||||
release the memory when you are done.
|
||||
As with copy_to_stream, this function will try use mmap where it can.
|
||||
|
||||
If you have an existing stream and need to be able to seek() it, you
|
||||
can use this function to copy the contents into a new stream that can
|
||||
be seek()ed:
|
||||
|
||||
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
|
||||
|
||||
It returns one of the following values:
|
||||
#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
|
||||
#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
|
||||
#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
|
||||
#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
|
||||
|
||||
make_seekable will always set newstream to be the stream that is valid
|
||||
if the function succeeds.
|
||||
When you have finished, remember to close the stream.
|
||||
|
||||
NOTE: If you only need to seek forwards, there is no need to call this
|
||||
function, as the php_stream_seek can emulate forward seeking when the
|
||||
whence parameter is SEEK_CUR.
|
||||
|
||||
NOTE: Writing to the stream may not affect the original source, so it
|
||||
only makes sense to use this for read-only use.
|
||||
|
||||
NOTE: If the origstream is network based, this function will block
|
||||
until the whole contents have been downloaded.
|
||||
|
||||
NOTE: Never call this function with an origstream that is referenced
|
||||
as a resource! It will close the origstream on success, and this
|
||||
can lead to a crash when the resource is later used/released.
|
||||
|
||||
NOTE: If you are opening a stream and need it to be seekable, use the
|
||||
STREAM_MUST_SEEK option to php_stream_open_wrapper();
|
||||
|
||||
Casting Streams
|
||||
===============
|
||||
What if your extension needs to access the FILE* of a user level file pointer?
|
||||
You need to "cast" the stream into a FILE*, and this is how you do it:
|
||||
|
||||
FILE * fp;
|
||||
php_stream * stream; /* already opened */
|
||||
|
||||
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
The prototype is:
|
||||
|
||||
PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
|
||||
show_err);
|
||||
|
||||
The show_err parameter, if non-zero, will cause the function to display an
|
||||
appropriate error message of type E_WARNING if the cast fails.
|
||||
|
||||
castas can be one of the following values:
|
||||
PHP_STREAM_AS_STDIO - a stdio FILE*
|
||||
PHP_STREAM_AS_FD - a generic file descriptor
|
||||
PHP_STREAM_AS_SOCKETD - a socket descriptor
|
||||
|
||||
If you ask a socket stream for a FILE*, the abstraction will use fdopen to
|
||||
create it for you. Be warned that doing so may cause buffered data to be lost
|
||||
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
|
||||
|
||||
If your system has the fopencookie function, php streams can synthesize a
|
||||
FILE* on top of any stream, which is useful for SSL sockets, memory based
|
||||
streams, data base streams etc. etc.
|
||||
|
||||
In situations where this is not desireable, 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 wierd 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,121 +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 php-dev@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 php/webserver
|
||||
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 php-dev@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.
|
||||
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!
|
||||
-175
@@ -1,175 +0,0 @@
|
||||
[IMPORTANT NOTICE]
|
||||
------------------
|
||||
Do _not_ ask to developers why some or all tests are failed under
|
||||
your environment! Let us know if you find why it fails. Thank you.
|
||||
|
||||
|
||||
[Testing Basics]
|
||||
----------------
|
||||
To execute test scripts, you must build PHP with some SAPI, then you
|
||||
type "make test" to execute all or some test scripts saved under
|
||||
"tests" directory under source root directory.
|
||||
|
||||
Usage:
|
||||
make test
|
||||
|
||||
"make test" basically executes "run-tests.php" script
|
||||
under source root. Therefore you can execute the script
|
||||
as follows
|
||||
|
||||
./sapi/cli/php -c /path/to/php.ini/ run-tests.php [ext/some_extension_name]
|
||||
|
||||
|
||||
|
||||
[Which "php" executable "make test" look for]
|
||||
---------------------------------------------
|
||||
"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.
|
||||
|
||||
If PHP is not build with CGI SAPI, "run-tests.php" script uses CLI
|
||||
SAPI. Tests that may not executed by CLI SAPI will be skipped.
|
||||
|
||||
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" force to use php.ini-dist as default config file. If
|
||||
you would like to test with other configuration file, user
|
||||
"run-tests.php" script.
|
||||
|
||||
Example:
|
||||
./sapi/cli/php -c /path/to/php.ini/ ext/standard
|
||||
|
||||
If you use php.ini other than php.ini-dist, you may see more failed
|
||||
tests.
|
||||
|
||||
|
||||
[Which test scripts are executed]
|
||||
---------------------------------
|
||||
"run-tests.php" ("make test") executes all test scripts by default
|
||||
by looking all directory named "tests". If there are files have "phpt"
|
||||
extension, "run-tests.php" takes test php code from the file and
|
||||
executes it.
|
||||
|
||||
Tester can easily executes tests selectively with as follows.
|
||||
|
||||
Example:
|
||||
./sapi/cli/php -c /path/to/php.ini/ run-tests.php ext/mbstring
|
||||
|
||||
|
||||
[Test results]
|
||||
--------------
|
||||
Test results are printed to standard output. If there is a failed test,
|
||||
"run-tests.php" script saves the result, expected result and code
|
||||
executed to the test script directory. For example, if
|
||||
ext/myext/tests/myext.phpt is failed to pass, following files are
|
||||
created:
|
||||
|
||||
ext/myext/tests/myext.out - output from test script
|
||||
ext/myext/tests/myext.exp - expected output
|
||||
ext/myext/tests/myext.php - test script executed
|
||||
|
||||
Tester can verify these files, if failed test is actually a bug
|
||||
or not.
|
||||
|
||||
|
||||
[Creating new test files]
|
||||
-------------------------
|
||||
Writing test file is very easy if you are used to PHP. Test file
|
||||
has following format. Here is a actual test file from iconv module.
|
||||
|
||||
===== ext/iconv/002.phpt =======
|
||||
--TEST--
|
||||
UCS4BE to ASCII
|
||||
--SKIPIF--
|
||||
<?php include('skipif.inc'); ?>
|
||||
--POST--
|
||||
--GET--
|
||||
--FILE--
|
||||
<?php include('002.inc'); ?>
|
||||
--EXPECT--
|
||||
abcd
|
||||
abcd
|
||||
===== end of ext/iconv/002.phpt =======
|
||||
|
||||
"--TEST--" is title of the test.
|
||||
"--SKIPIF--" is condition when to skip this test.
|
||||
"--POST--" is POST variable passed to test script.
|
||||
"--GET--" is GET variable passed to test script.
|
||||
"--FILE--" is the test script.
|
||||
"--EXPECT--" is the expected output from the test script.
|
||||
|
||||
ext/iconv/002.phpt uses 2 files. "skipif.inc" is used to skip
|
||||
test when test cannot be performed such as iconv module is not
|
||||
compiled or loaded.
|
||||
|
||||
==== ext/iconv/skipif.inc ====
|
||||
<?php
|
||||
// This script prints "skip" if condition does not meet.
|
||||
|
||||
if (!extension_loaded("iconv") && ini_get("enable_dl")) {
|
||||
$dlext = (substr(PHP_OS, 0, 3) == "WIN") ? ".dll" : ".so";
|
||||
@dl("iconv$dlext");
|
||||
}
|
||||
if (!extension_loaded("iconv")) {
|
||||
die("skip\n");
|
||||
}
|
||||
?>
|
||||
==== end of ext/iconv/skipif.inc ====
|
||||
|
||||
ext/inconv/002.inc is the test script. "run-tests.php" script
|
||||
executes test script with CGI executable.
|
||||
|
||||
==== ext/iconv/002.inc ===
|
||||
<?php
|
||||
/*
|
||||
Expected output:
|
||||
abcd
|
||||
abcd
|
||||
*/
|
||||
|
||||
$s = unpack("V*", iconv("ascii","UCS-4LE", "abcd"));
|
||||
foreach($s as $c) { print "&#$c;"; } print "\n";
|
||||
|
||||
$s = pack("NNNN", 97, 98, 99, 100);
|
||||
$q = iconv("UCS-4BE", "ascii", $s);
|
||||
print $q; print "\n";
|
||||
?>
|
||||
=== end of ext/iconv/002.inc ===
|
||||
|
||||
Test script and skipif code may be directly write into *.phpt.
|
||||
However, it is recommended to use other files for ease of writing
|
||||
test script. For instance, you can execute test script under
|
||||
ext/iconv as follows:
|
||||
|
||||
./sapi/cli/php -c /path/to/php.ini/ ext/iconv
|
||||
|
||||
|
||||
[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);
|
||||
|
||||
?>
|
||||
@@ -1,123 +0,0 @@
|
||||
PHP Build System V5 Overview
|
||||
|
||||
- supports Makefile.ins during transition phase
|
||||
- not-really-portable Makefile includes have been eliminated
|
||||
- supports seperate 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 dependending on the user's
|
||||
wishes, the extension will even be built as a dynamic module.
|
||||
|
||||
The full syntax:
|
||||
|
||||
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
|
||||
|
||||
Please have a look at acinclude.m4 for the gory details and meanings
|
||||
of the other parameters.
|
||||
|
||||
And that's basically it for the extension side.
|
||||
|
||||
If you previously built sub-libraries for this module, add
|
||||
the source-code files here as well. If you need to specify
|
||||
separate include directories, do it this way:
|
||||
|
||||
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
|
||||
|
||||
E.g. this builds the three files which are located relative to the
|
||||
extension source directory and compiles all three files with the
|
||||
special include directive (@ext_srcdir@ is automatically replaced).
|
||||
|
||||
Now, you need to tell the build system that you want to build files
|
||||
in a directory called $ext_builddir/lib:
|
||||
|
||||
PHP_ADD_BUILD_DIR($ext_builddir/lib)
|
||||
|
||||
Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
|
||||
is only set by the latter.
|
||||
|
||||
If you have a complex extension, you might to need add special
|
||||
Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
|
||||
in your config.m4 after PHP_NEW_EXTENSION.
|
||||
|
||||
This will read a file in the source-dir of your extension called
|
||||
Makefile.frag. In this file, $(builddir) and $(srcdir) will be
|
||||
replaced by the values which are correct for your extension
|
||||
and which are again determined by the PHP_NEW_EXTENSION macro.
|
||||
|
||||
Make sure to prefix *all* relative paths correctly with either
|
||||
$(builddir) or $(srcdir). Because the build system does not
|
||||
change the working directory anymore, we must use either
|
||||
absolute paths or relative ones to the top build-directory.
|
||||
Correct prefixing ensures that.
|
||||
|
||||
|
||||
SAPI developers:
|
||||
|
||||
Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
|
||||
|
||||
PHP_SELECT_SAPI(name, type, sources.c)
|
||||
|
||||
I.e. specify the source-code files as above and also pass the
|
||||
information regarding how PHP is supposed to be built (shared
|
||||
module, program, etc).
|
||||
|
||||
For example for APXS:
|
||||
|
||||
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php4.c php_apache.c)
|
||||
|
||||
|
||||
|
||||
General info
|
||||
|
||||
The foundation for the new system is the flexible handling of
|
||||
sources and their contexts. With the help of macros you
|
||||
can define special flags for each source-file, where it is
|
||||
located, in which target context it can work, etc.
|
||||
|
||||
Have a look at the well documented macros
|
||||
PHP_ADD_SOURCES(_X) in acinclude.m4.
|
||||
@@ -0,0 +1,59 @@
|
||||
Windows 95/NT Specific Notes on Compilation
|
||||
|
||||
Windows compilation has only been tested with Microsoft Visual C++
|
||||
Version 5 Standard Edition. The PHP executable has only had limited
|
||||
testing under Windows 95. SAFE MODE and any User or Group functionality
|
||||
has not been ported/tested.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Compiling PHP with MSVC5
|
||||
|
||||
There are three msvc workspaces provided with this distribution. The one
|
||||
most people will use is php3.dsw. This contains project files for two
|
||||
versions on PHP, one with mySQL compiled internaly, and one without (both
|
||||
have ODBC internaly compiled). It also contains all the modules.
|
||||
|
||||
The next workspace is php3extras.dsw. This project contains the converter
|
||||
and a program called phpwatch, which is a simple program to watch debugger
|
||||
output under windows. The 'socket' program is also available from the php
|
||||
site, which is a better alternative to phpwatch.
|
||||
|
||||
The third workspace is php3sapi.dsw. These projects are experimental and
|
||||
will probably not compile most of the time. It contains preliminary work
|
||||
on the server api's for windows.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Base Configuration and Configuration Issues
|
||||
|
||||
*The base configuration for the windows php version contains odbc
|
||||
support. Support for other database modules will be provided as external dll files.
|
||||
*ODBC can be used to connect to many of the databases previously
|
||||
supported by php (though they can still be compiled in if you have
|
||||
the libraries!)
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Makefiles
|
||||
|
||||
Be sure to edit any windows makefile and change the include directories
|
||||
to be appropriate for your system.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
CGI Version
|
||||
|
||||
The makefile for the cgi version of php is located in the win32
|
||||
subdirectory of the php source tree. This make file is specificaly
|
||||
for Visual C++ V5.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
ISAPI/NSAPI/WSAPI/Apache Versions
|
||||
|
||||
These versions are not yet working. They are located in the php3sapi.dsw
|
||||
workspace.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Other Libraries
|
||||
|
||||
See the php faq at php.net for information on where to obtain the various
|
||||
libraries needed to compile some modules.
|
||||
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
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:
|
||||
|
||||
* 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.
|
||||
|
||||
|
||||
Quick guide to installing FastCGI with Zeus
|
||||
-------------------------------------------
|
||||
|
||||
Step 1 - obtain and install FastCGI development kit.
|
||||
|
||||
Grab the package from:
|
||||
http://www.fastcgi.com/dist/devkit_2.2.0.tar.gz
|
||||
|
||||
Extract the package and follow the instructions:
|
||||
./configure
|
||||
make
|
||||
make export
|
||||
(run the last as root)
|
||||
|
||||
This will install to /usr/local/lib/libfcgi.a
|
||||
and /usr/local/include/*fcgi*
|
||||
|
||||
|
||||
|
||||
Step 2 - Compile PHP as FastCGI.
|
||||
|
||||
Compile as follows:
|
||||
./configure --with-fastcgi
|
||||
make
|
||||
|
||||
Note that PHP has many options to the configure script -
|
||||
e.g. --with-mysql. You will probably want to select your usual options
|
||||
before compiling; the above is just a bare minimum, for illustration.
|
||||
|
||||
After compilation finishes, you will be left with an executable
|
||||
program called 'php'. Copy this into your document root, under a
|
||||
dedicated FastCGI directory (e.g. $DOCROOT/fcgi-bin/php)
|
||||
|
||||
|
||||
Step 3 - configure Zeus
|
||||
|
||||
Four stages:
|
||||
- enable FastCGI
|
||||
- configure FastCGI
|
||||
- setup alias for FastCGI
|
||||
- setup alias for PHP
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Step 4 - start PHP as a FastCGI runner
|
||||
|
||||
When you start PHP, it will pre-fork a given number of child processes
|
||||
to handle incoming PHP requests. Each process will handle a given
|
||||
number of requests before exiting (and being replaced by a newly
|
||||
forked process). You can control these two parameters by setting the
|
||||
following environment variables BEFORE starting the FastCGI runner:
|
||||
|
||||
PHP_FCGI_CHILDREN - the number of child processes to pre-fork. If not
|
||||
set, defaults to 8.
|
||||
|
||||
PHP_FCGI_MAX_REQUESTS - the number of requests each PHP child process
|
||||
handles before exiting. If not set, defaults to 500.
|
||||
|
||||
To start the FastCGI runner, execute '$ZEUSHOME/web/bin/fcgirunner
|
||||
8002 $DOCROOT/fcgi-bin/php'. Substitute the appropriate values for
|
||||
$ZEUSHOME and $DOCROOT; also substitute for 8002 the port you chose,
|
||||
above.
|
||||
|
||||
To stop the runner (e.g. to experiment with the above environment
|
||||
variables) you will need to manually stop and running PHP
|
||||
processes. (Use 'ps' and 'kill'). As it is PHP which is forking lots
|
||||
of children and not the runner, Zeus unfortunately cannot keep track
|
||||
of what processes are running, sorry. A typical command line may look
|
||||
like 'ps -efl | grep $DOCROOT/fcgi-bin/php | grep -v grep | awk
|
||||
'{print $4}' | xargs kill'
|
||||
@@ -1,170 +1,100 @@
|
||||
Things to do or at least think about doing in the future. Name in
|
||||
parenthesis means that person has taken on this project.
|
||||
$Id$
|
||||
|
||||
Zend
|
||||
----
|
||||
For PHP 4.3.0:
|
||||
* Allow foreach ($array as $k => &$val) syntax. right now we cannot
|
||||
traverse an array without copying each element.
|
||||
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
|
||||
dimensional arrays.
|
||||
* Look at replacing c-lib call tolower().
|
||||
* Make hash API functions work with HASH_OF() to save time.
|
||||
* Allow to set a default value for call-by-reference-parameters.
|
||||
eg: function hello (&$pallo = NULL) {}
|
||||
* Disallow function(method) redefinition in class.
|
||||
* Add configure test to determine if dlsym() requires underscore and set
|
||||
DLSYM_NEEDS_UNDERSCORE accordingly. Perl and zsh have it in configure,
|
||||
for example. (DONE?)
|
||||
+----
|
||||
| * -- to be done
|
||||
| ? -- to be done sometime if possible
|
||||
| P -- in progress (name should appear in parentheses after task)
|
||||
| D -- delayed until later date (specify in parentheses after task)
|
||||
| U -- done, untested
|
||||
| V -- done
|
||||
+----
|
||||
|
||||
For PHP 5.0.0:
|
||||
* Native large number support (probably with GNU GMP)
|
||||
* Const'ify APIs. Right now, many functions leave parameters untouched,
|
||||
but don't declare those as const. This makes interaction with other
|
||||
interfaces difficult which pass const parameters to us.
|
||||
Configuration Issues
|
||||
--------------------
|
||||
* properly detect dbm routines when they're in libc
|
||||
* add the appropriate #define magic for memmove and friends (see
|
||||
GNU autoconf info pages for details)
|
||||
* make it possible to disable support for some extensions (gd, dbm)
|
||||
* make it possible to build selected extensions so they are
|
||||
dynamically-loadable
|
||||
|
||||
Core Language Issues
|
||||
--------------------
|
||||
* go through PHP2's php.h and see how each special #define might be
|
||||
applied/supported in PHP3
|
||||
* move Treatdata() to language-scanner.lex where hash_environment()
|
||||
is called including a decision about priority of variables and moving
|
||||
Treatdata() to use hash_add() instead of hash_update() for insertions
|
||||
to the symbol table.
|
||||
* go through FIXME and XXX lines (egrep 'FIXME|XXX' *.[ch])
|
||||
* make lexer and parser thread-safe
|
||||
* verify that binary strings are handled correctly
|
||||
V don't evaluate truth expressions more than once
|
||||
V make unset() work on arrays (tricky)
|
||||
|
||||
Core Functions
|
||||
--------------
|
||||
* go through all file functions and make sure they are opened in binary
|
||||
mode in win32 if needed (ie copy)
|
||||
* go through all functions and look at PHP_SAFE_MODE issues
|
||||
* have a look at return codes of fsockopen() function - we should
|
||||
probably RETURN_FALSE and then set an error code somewhere (Rasmus)
|
||||
* go through FIXME and XXX lines (egrep 'FIXME|XXX' functions/*.[ch])
|
||||
* add user-level flock() implementation to let people lock and unlock files
|
||||
* add "'" modifier to sprintf to group thousands by comma
|
||||
* Add an improved eval() that doesn't "leak"
|
||||
? sorting of objects with a user-defined comparison function (like Perl)
|
||||
(this shouldn't be expected before 3.1, if at all).
|
||||
|
||||
|
||||
global
|
||||
------
|
||||
For PHP 4.3.0:
|
||||
* Add aliases to functions to conform to new naming conventions, e.g.
|
||||
str_to_upper().
|
||||
* Make all extensions thread-safe.
|
||||
* Make everything on the language-level independent of your locale
|
||||
settings.
|
||||
* Change PHP error messages, so that they point to pages or sections
|
||||
in the PHP Manual.
|
||||
* Make sure that all ZTS globals get destructed. Most ts_allocate_id()
|
||||
calls should have a dtor entry.
|
||||
* Activate all extensions by default that don't rely on external
|
||||
dependencies. (eg ftp) (DONE?)
|
||||
* on some platforms unimplemented function will just do nothing
|
||||
(e.g. symlink) they should print a warning or not even be defined!
|
||||
(DONE ?)
|
||||
* Use arg_separator.input to implode args in the CGI sapi extension
|
||||
and arg_separator.input to explode in php_build_argv(). (DONE?)
|
||||
* Change the odbc_fetch_into() function to require ALWAYS the first two
|
||||
parameters ($conn_id and $array), and make the third (row) be optional.
|
||||
* Remove --with-openlink configure option (--with-iodbc replaces it).
|
||||
* Implement flush feature suitable for nested output buffers.
|
||||
Extensions
|
||||
----------
|
||||
* add version strings for all extensions
|
||||
* Oracle persistent connections
|
||||
U gd support for windows
|
||||
* Illustra support (APIS)
|
||||
? CQL++ support (http://www.cql.com/)
|
||||
? GNU SQL support (does anybody actually use this?)
|
||||
? DB2 support (http://www.sleepycat.com/)
|
||||
? Shore support (http://www.cs.wisc.edu/shore/)
|
||||
? PGP Interface (use PGPlib?)
|
||||
? more Perl-like regex handling?
|
||||
|
||||
For PHP 5.0.0
|
||||
* bundle and use curl lib for fopen wrapper.
|
||||
* --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?).
|
||||
* 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.
|
||||
Server Support
|
||||
--------------
|
||||
P ISAPI (Shane)
|
||||
* process cookies
|
||||
* blocking functions
|
||||
* make sure it's Microsoft-clean so it can be used with other ISAPI
|
||||
implementations
|
||||
* WSAPI
|
||||
* NSAPI
|
||||
* process cookies
|
||||
* check POST method handling code
|
||||
* use Netscape memory allocation inside emalloc() and company
|
||||
* FastCGI support - see http://fastcgi.idle.com/
|
||||
|
||||
Win32 Specific
|
||||
--------------
|
||||
* implement some kind of syslog->file log support for win95.
|
||||
* change all file open/read/write functions from c library to win32
|
||||
api file functions. The win32 api functions handle both disk files
|
||||
and network files. This will allow include and require to use http
|
||||
or ftp files as the unix version does, and do away with my
|
||||
workaround to support this. (3.1?)
|
||||
* implement symlinks via windows shell links (shortcuts). This will
|
||||
work only at the script level and is not a c language level port.
|
||||
|
||||
Other
|
||||
* use thread-safe resolver functions (either require BIND 8 or adns).
|
||||
* implement javadoc based function docs template system.
|
||||
* provide optional IPv6 support.
|
||||
* find a better way to implement script timeouts. SIGVTALRM is used
|
||||
by some POSIX threads implementations (i.e. OpenBSD) and is not
|
||||
available in ZTS mode.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
ext/bz2
|
||||
Testing
|
||||
-------
|
||||
* Add ini setting for decompression buffer size. The default 4k is to small
|
||||
for big files and takes ages to decompress. However, 40k which perform
|
||||
quite good with big files may be to much under certain environments as
|
||||
default setting. There should be consideren different default sizes for
|
||||
different SAPIS (e.g. apache and cli).
|
||||
* truss/strace a typical PHP request and see if there are some system
|
||||
calls that could be optimized out
|
||||
* verify that regression tests exist for all core functions
|
||||
|
||||
ext/curl
|
||||
--------
|
||||
* Have a warning scheme for when people use unsupported features.
|
||||
|
||||
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/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.
|
||||
|
||||
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
|
||||
locked individually.
|
||||
* Write a network-transparent storage back-end with fallover
|
||||
facilities
|
||||
* Provide a callback facility which is executed upon encountering
|
||||
an unknown class name during deserialization
|
||||
|
||||
ext/sockets
|
||||
-----------
|
||||
* Implement IPv6
|
||||
* Review/Fix vectors
|
||||
|
||||
ext/standard
|
||||
------------
|
||||
* Add a version number to data serialized via serialize().
|
||||
* Possibly modify parsing of GPC data to automatically create arrays if
|
||||
variable name is seen more than once.
|
||||
* Implement regex-cache for url-functions.
|
||||
* stri_replace(). (Andrei)
|
||||
* Move socket related functions to fsock.c.
|
||||
* NOT binary safe:
|
||||
strtok()
|
||||
basename()
|
||||
dirname()
|
||||
strrpos()
|
||||
strrchr()
|
||||
strip_tags()
|
||||
|
||||
ext/wddx
|
||||
--------
|
||||
* See if we can support the remaining data types:
|
||||
dateTime
|
||||
binary
|
||||
|
||||
http://www.wddx.org/WDDX_SDK_10a/7__References/WDDX_DTD.htm
|
||||
(Andrei)
|
||||
|
||||
* implement wddx_packet_as_javascript(). (Andrei)
|
||||
|
||||
other cool stuff
|
||||
----------------
|
||||
* PVM extension
|
||||
Miscellaneous
|
||||
-------------
|
||||
* remove hard-coded compilation options
|
||||
? locale issues - funny things happen in PHP2 when the locale is set to
|
||||
use , instead of . as the decimal seperator. ie. 1.5+1.5 = 1
|
||||
? SSI->PHP3 conversion script
|
||||
? SQL-based access logging (start with examples/log-*.php3)
|
||||
@@ -1,3 +0,0 @@
|
||||
- clean up .cvsignores
|
||||
- purge Makefile.ins and replace PHP_EXTENSION in config.m4s
|
||||
with appropiate calls to PHP_NEW_EXTENSION
|
||||
@@ -1,26 +0,0 @@
|
||||
Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Neither name of the copyright holders nor the names of their contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
|
||||
IS'' AND ANY EXPRESS 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 THE COPYRIGHT HOLDERS OR
|
||||
CONTRIBUTORS 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.
|
||||
@@ -1,6 +0,0 @@
|
||||
## process this file with automake to produce Makefile.am
|
||||
AUTOMAKE_OPTIONS=foreign
|
||||
noinst_LTLIBRARIES=libtsrm.la
|
||||
libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c
|
||||
|
||||
depend:
|
||||
@@ -1,2 +0,0 @@
|
||||
- Improve the lock in ts_resource_ex() in order to cover less code.
|
||||
This can probably be done by more careful hash table access
|
||||
-603
@@ -1,603 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski|
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef ZTS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
typedef struct _tsrm_tls_entry tsrm_tls_entry;
|
||||
|
||||
struct _tsrm_tls_entry {
|
||||
void **storage;
|
||||
int count;
|
||||
THREAD_T thread_id;
|
||||
tsrm_tls_entry *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
ts_allocate_ctor ctor;
|
||||
ts_allocate_dtor dtor;
|
||||
} tsrm_resource_type;
|
||||
|
||||
|
||||
/* The memory manager table */
|
||||
static tsrm_tls_entry **tsrm_tls_table=NULL;
|
||||
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 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;
|
||||
|
||||
/* Debug support */
|
||||
int tsrm_error(int level, const char *format, ...);
|
||||
|
||||
/* 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
|
||||
#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;
|
||||
#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)
|
||||
{
|
||||
#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();
|
||||
#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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tsmm_mutex = tsrm_mutex_alloc();
|
||||
|
||||
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));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Shutdown TSRM (call once for the entire process) */
|
||||
TSRM_API void tsrm_shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tsrm_tls_table) {
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
|
||||
|
||||
while (p) {
|
||||
int j;
|
||||
|
||||
next_p = p->next;
|
||||
for (j=0; j<id_count; j++) {
|
||||
free(p->storage[j]);
|
||||
}
|
||||
free(p->storage);
|
||||
free(p);
|
||||
p = next_p;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
#if defined(GNUPTH)
|
||||
pth_kill();
|
||||
#elif defined(PTHREADS)
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", 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));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
|
||||
/* enlarge the arrays for the already active threads */
|
||||
for (i=0; i<tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count < id_count) {
|
||||
int j;
|
||||
|
||||
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
|
||||
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);
|
||||
}
|
||||
}
|
||||
p->count = id_count;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
|
||||
return *rsrc_id;
|
||||
}
|
||||
|
||||
|
||||
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
|
||||
{
|
||||
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);
|
||||
#endif
|
||||
|
||||
if (tsrm_new_thread_begin_handler) {
|
||||
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
for (i=0; i<id_count; i++) {
|
||||
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
||||
if (resource_types_table[i].ctor) {
|
||||
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i], &(*thread_resources_ptr)->storage);
|
||||
}
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
|
||||
if (tsrm_new_thread_end_handler) {
|
||||
tsrm_new_thread_end_handler(thread_id, &((*thread_resources_ptr)->storage));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
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;
|
||||
|
||||
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);
|
||||
#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 {
|
||||
thread_id = *th_id;
|
||||
}
|
||||
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
if (!thread_resources) {
|
||||
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
|
||||
return ts_resource_ex(id, &thread_id);
|
||||
} else {
|
||||
do {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
thread_resources = thread_resources->next;
|
||||
} else {
|
||||
allocate_new_resource(&thread_resources->next, thread_id);
|
||||
return ts_resource_ex(id, &thread_id);
|
||||
/*
|
||||
* thread_resources = thread_resources->next;
|
||||
* break;
|
||||
*/
|
||||
}
|
||||
} while (thread_resources);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* 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 *last=NULL;
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
||||
thread_resources = tsrm_tls_table[hash_value];
|
||||
|
||||
while (thread_resources) {
|
||||
if (thread_resources->thread_id == thread_id) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
#if defined(PTHREADS)
|
||||
pthread_setspecific(tls_key, 0);
|
||||
#elif defined(TSRM_WIN32)
|
||||
TlsSetValue(tls_key, 0);
|
||||
#endif
|
||||
free(thread_resources);
|
||||
break;
|
||||
}
|
||||
if (thread_resources->next) {
|
||||
last = thread_resources;
|
||||
}
|
||||
thread_resources = thread_resources->next;
|
||||
}
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
void ts_free_id(ts_rsrc_id id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Utility Functions
|
||||
*/
|
||||
|
||||
/* Obtain the current thread id */
|
||||
TSRM_API THREAD_T tsrm_thread_id(void)
|
||||
{
|
||||
#ifdef TSRM_WIN32
|
||||
return GetCurrentThreadId();
|
||||
#elif defined(NETWARE)
|
||||
return NXThreadGetId();
|
||||
#elif defined(GNUPTH)
|
||||
return pth_self();
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_self();
|
||||
#elif defined(NSAPI)
|
||||
return systhread_current();
|
||||
#elif defined(PI3WEB)
|
||||
return PIThread_getCurrent();
|
||||
#elif defined(TSRM_ST)
|
||||
return st_thread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a mutex */
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
||||
{
|
||||
MUTEX_T mutexp;
|
||||
#ifdef NETWARE
|
||||
long flags = 0; /* Don't require NX_MUTEX_RECURSIVE, I guess */
|
||||
NXHierarchy_t order = 0;
|
||||
NX_LOCK_INFO_ALLOC (lockInfo, "PHP-TSRM", 0);
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
||||
InitializeCriticalSection(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
mutexp = NXMutexAlloc(flags, order, &lockInfo); /* return value ignored for now */
|
||||
#elif defined(GNUPTH)
|
||||
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
||||
pth_mutex_init(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(mutexp,NULL);
|
||||
#elif defined(NSAPI)
|
||||
mutexp = crit_init();
|
||||
#elif defined(PI3WEB)
|
||||
mutexp = PIPlatform_allocLocalMutex();
|
||||
#elif defined(TSRM_ST)
|
||||
mutexp = st_mutex_new();
|
||||
#endif
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex created thread: %d\n",mythreadid());
|
||||
#endif
|
||||
return( mutexp );
|
||||
}
|
||||
|
||||
|
||||
/* Free a mutex */
|
||||
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
||||
{
|
||||
if (mutexp) {
|
||||
#ifdef TSRM_WIN32
|
||||
DeleteCriticalSection(mutexp);
|
||||
#elif defined(NETWARE)
|
||||
NXMutexFree(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
free(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
pthread_mutex_destroy(mutexp);
|
||||
free(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
crit_terminate(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
PISync_delete(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
st_mutex_destroy(mutexp);
|
||||
#endif
|
||||
}
|
||||
#ifdef THR_DEBUG
|
||||
printf("Mutex freed thread: %d\n",mythreadid());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Lock a mutex */
|
||||
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
EnterCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
return NXLock(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_acquire(mutexp, 0, NULL);
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_lock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
return crit_enter(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_lock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_lock(mutexp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Unlock a mutex */
|
||||
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
||||
{
|
||||
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld", tsrm_thread_id()));
|
||||
#ifdef TSRM_WIN32
|
||||
LeaveCriticalSection(mutexp);
|
||||
return 1;
|
||||
#elif defined(NETWARE)
|
||||
return NXUnlock(mutexp);
|
||||
#elif defined(GNUPTH)
|
||||
return pth_mutex_release(mutexp);
|
||||
#elif defined(PTHREADS)
|
||||
return pthread_mutex_unlock(mutexp);
|
||||
#elif defined(NSAPI)
|
||||
return crit_exit(mutexp);
|
||||
#elif defined(PI3WEB)
|
||||
return PISync_unlock(mutexp);
|
||||
#elif defined(TSRM_ST)
|
||||
return st_mutex_unlock(mutexp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_begin_handler;
|
||||
|
||||
tsrm_new_thread_begin_handler = new_thread_begin_handler;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler)
|
||||
{
|
||||
void *retval = (void *) tsrm_new_thread_end_handler;
|
||||
|
||||
tsrm_new_thread_end_handler = new_thread_end_handler;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Debug support
|
||||
*/
|
||||
|
||||
#if TSRM_DEBUG
|
||||
int tsrm_error(int level, const char *format, ...)
|
||||
{
|
||||
if (level<=tsrm_error_level) {
|
||||
va_list args;
|
||||
int size;
|
||||
|
||||
fprintf(tsrm_error_file, "TSRM: ");
|
||||
va_start(args, format);
|
||||
size = vfprintf(tsrm_error_file, 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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
#endif /* ZTS */
|
||||
-186
@@ -1,186 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="TSRM" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=TSRM - Win32 Debug_TS
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "TSRM.mak" CFG="TSRM - Win32 Debug_TS"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!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
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "TSRM - Win32 Debug_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Debug_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug_TS"
|
||||
# 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 BASE RSC /l 0x40d /d "_DEBUG"
|
||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "TSRM - Win32 Release_TS"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TS"
|
||||
# PROP Intermediate_Dir "Release_TS"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /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 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_TS_inline"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "TSRM___Win32_Release_TS_inline"
|
||||
# PROP BASE Intermediate_Dir "TSRM___Win32_Release_TS_inline"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release_TS_inline"
|
||||
# PROP Intermediate_Dir "Release_TS_inline"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /D "NDEBUG" /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 BASE RSC /l 0x40d /d "NDEBUG"
|
||||
# ADD RSC /l 0x40d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "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"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TSRM.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_strtok_r.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
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
|
||||
|
||||
SOURCE=.\tsrm_config.w32.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_config_common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_strtok_r.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_virtual_cwd.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tsrm_win32.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Thread Safe Resource Manager |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1999, 2000, Andi Gutmans, Sascha Schumann, Zeev Suraski|
|
||||
| This source file is subject to the TSRM license, that is bundled |
|
||||
| with this package in the file LICENSE |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef TSRM_H
|
||||
#define TSRM_H
|
||||
|
||||
/* #ifndef WIN32 */
|
||||
#if !defined(WIN32) && !defined(NETWARE)
|
||||
# include "tsrm_config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# define TSRM_WIN32
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifdef TSRM_EXPORTS
|
||||
# define TSRM_API __declspec(dllexport)
|
||||
# else
|
||||
# define TSRM_API __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define TSRM_API
|
||||
#endif
|
||||
|
||||
/* Only compile multi-threading functions if we're in ZTS mode */
|
||||
#ifdef ZTS
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include <windows.h>
|
||||
#elif defined(NETWARE)
|
||||
# include <nks/thread.h>
|
||||
# include <nks/synch.h>
|
||||
#elif defined(GNUPTH)
|
||||
# include <pth.h>
|
||||
#elif defined(PTHREADS)
|
||||
# include <pthread.h>
|
||||
#elif defined(TSRM_ST)
|
||||
# include <st.h>
|
||||
#endif
|
||||
|
||||
typedef int ts_rsrc_id;
|
||||
|
||||
/* Define THREAD_T and MUTEX_T */
|
||||
#ifdef TSRM_WIN32
|
||||
# define THREAD_T DWORD
|
||||
# define MUTEX_T CRITICAL_SECTION *
|
||||
#elif defined(NETWARE)
|
||||
# define THREAD_T NXThreadId_t
|
||||
# define MUTEX_T NXMutex_t *
|
||||
#elif defined(GNUPTH)
|
||||
# define THREAD_T pth_t
|
||||
# define MUTEX_T pth_mutex_t *
|
||||
#elif defined(PTHREADS)
|
||||
# define THREAD_T pthread_t
|
||||
# define MUTEX_T pthread_mutex_t *
|
||||
#elif defined(NSAPI)
|
||||
# define THREAD_T SYS_THREAD
|
||||
# define MUTEX_T CRITICAL
|
||||
#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
|
||||
#endif
|
||||
|
||||
typedef void (*ts_allocate_ctor)(void *, void ***);
|
||||
typedef void (*ts_allocate_dtor)(void *, void ***);
|
||||
|
||||
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* startup/shutdown */
|
||||
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
|
||||
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);
|
||||
|
||||
/* fetches the requested resource for the current thread */
|
||||
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
|
||||
#define ts_resource(id) ts_resource_ex(id, NULL)
|
||||
|
||||
/* frees all resources allocated for the current thread */
|
||||
TSRM_API void ts_free_thread(void);
|
||||
|
||||
/* deallocates all occurrences of a given id */
|
||||
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);
|
||||
|
||||
/* utility functions */
|
||||
TSRM_API THREAD_T tsrm_thread_id(void);
|
||||
TSRM_API MUTEX_T tsrm_mutex_alloc(void);
|
||||
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
|
||||
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
|
||||
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
|
||||
|
||||
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
|
||||
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
|
||||
|
||||
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
||||
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
|
||||
|
||||
#define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
|
||||
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
||||
#define TSRMLS_D void ***tsrm_ls
|
||||
#define TSRMLS_DC , TSRMLS_D
|
||||
#define TSRMLS_C tsrm_ls
|
||||
#define TSRMLS_CC , TSRMLS_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* non ZTS */
|
||||
|
||||
#define TSRMLS_FETCH()
|
||||
#define TSRMLS_D void
|
||||
#define TSRMLS_DC
|
||||
#define TSRMLS_C
|
||||
#define TSRMLS_CC
|
||||
|
||||
#endif /* ZTS */
|
||||
|
||||
#endif /* TSRM_H */
|
||||
@@ -1 +0,0 @@
|
||||
#undef PTHREADS
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
|
||||
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
|
||||
])
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Makefile to generate build tools
|
||||
#
|
||||
# Standard usage:
|
||||
# make -f build.mk
|
||||
#
|
||||
# Written by Sascha Schumann
|
||||
#
|
||||
# $Id$
|
||||
|
||||
|
||||
LT_TARGETS = ltmain.sh ltconfig
|
||||
|
||||
config_h_in = tsrm_config.h.in
|
||||
|
||||
makefile_am_files = Makefile.am
|
||||
makefile_in_files = $(makefile_am_files:.am=.in)
|
||||
makefile_files = $(makefile_am_files:e.am=e)
|
||||
|
||||
targets = $(makefile_in_files) $(LT_TARGETS) configure $(config_h_in)
|
||||
|
||||
all: $(targets)
|
||||
|
||||
clean:
|
||||
rm -f $(targets)
|
||||
|
||||
$(LT_TARGETS):
|
||||
rm -f $(LT_TARGETS)
|
||||
libtoolize --automake $(AMFLAGS) -f
|
||||
|
||||
$(makefile_in_files): $(makefile_am_files)
|
||||
automake -a -i $(AMFLAGS) $(makefile_files)
|
||||
|
||||
aclocal.m4: configure.in acinclude.m4
|
||||
aclocal
|
||||
|
||||
$(config_h_in): configure.in acconfig.h
|
||||
# explicitly remove target since autoheader does not seem to work
|
||||
# correctly otherwise (timestamps are not updated)
|
||||
@rm -f $@
|
||||
autoheader
|
||||
|
||||
configure: aclocal.m4 configure.in
|
||||
autoconf
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
case "$1" in
|
||||
--copy)
|
||||
automake_flags=--copy
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
libtoolize --force --automake $automake_flags
|
||||
|
||||
mv aclocal.m4 aclocal.m4.old 2>/dev/null
|
||||
aclocal
|
||||
if cmp aclocal.m4.old aclocal.m4 > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}aclocal.m4"
|
||||
mv aclocal.m4.old aclocal.m4
|
||||
else
|
||||
echo "buildconf: created or modified ${1}aclocal.m4"
|
||||
fi
|
||||
|
||||
autoheader
|
||||
|
||||
automake --add-missing --include-deps $automake_flags
|
||||
|
||||
mv configure configure.old 2>/dev/null
|
||||
autoconf
|
||||
if cmp configure.old configure > /dev/null 2>&1; then
|
||||
echo "buildconf: keeping ${1}configure"
|
||||
mv configure.old configure
|
||||
else
|
||||
echo "buildconf: created or modified ${1}configure"
|
||||
fi
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl Minimalistic configure.in for TSRM.
|
||||
dnl
|
||||
|
||||
AC_INIT(TSRM.c)
|
||||
AM_INIT_AUTOMAKE(TSRM, 1.0, nodefine)
|
||||
AM_CONFIG_HEADER(tsrm_config.h)
|
||||
|
||||
sinclude(tsrm.m4)
|
||||
|
||||
TSRM_BASIC_CHECKS
|
||||
TSRM_THREADS_CHECKS
|
||||
|
||||
AM_PROG_LIBTOOL
|
||||
if test "$enable_debug" != "yes"; then
|
||||
AM_SET_LIBTOOL_VARIABLE([--silent])
|
||||
fi
|
||||
|
||||
dnl TSRM_PTHREAD
|
||||
|
||||
AC_CHECK_HEADERS(
|
||||
utime.h \
|
||||
dirent.h \
|
||||
stdarg.h \
|
||||
alloca.h \
|
||||
unistd.h \
|
||||
limits.h
|
||||
)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef READDIR_H
|
||||
#define READDIR_H
|
||||
|
||||
|
||||
/*
|
||||
* Structures and types used to implement opendir/readdir/closedir
|
||||
* on Windows 95/NT.
|
||||
*/
|
||||
|
||||
#include <io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
/* struct dirent - same as Unix */
|
||||
|
||||
struct dirent {
|
||||
long d_ino; /* inode (always 1 in WIN32) */
|
||||
off_t d_off; /* offset to this dirent */
|
||||
unsigned short d_reclen; /* length of d_name */
|
||||
char d_name[_MAX_FNAME + 1]; /* filename (null terminated) */
|
||||
};
|
||||
|
||||
|
||||
/* typedef DIR - not the same as Unix */
|
||||
typedef struct {
|
||||
long handle; /* _findfirst/_findnext handle */
|
||||
short offset; /* offset into directory */
|
||||
short finished; /* 1 if there are not more files */
|
||||
struct _finddata_t fileinfo; /* from _findfirst/_findnext */
|
||||
char *dir; /* the dir we are reading */
|
||||
struct dirent dent; /* the dirent to return */
|
||||
} DIR;
|
||||
|
||||
/* Function prototypes */
|
||||
DIR *opendir(const char *);
|
||||
struct dirent *readdir(DIR *);
|
||||
int readdir_r(DIR *, struct dirent *, struct dirent **);
|
||||
int closedir(DIR *);
|
||||
void rewinddir(DIR *);
|
||||
|
||||
|
||||
#endif /* READDIR_H */
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
dnl Copyright (c) 1999, 2000 Sascha Schumann. All rights reserved.
|
||||
dnl
|
||||
dnl Redistribution and use in source and binary forms, with or without
|
||||
dnl modification, are permitted provided that the following conditions
|
||||
dnl are met:
|
||||
dnl
|
||||
dnl 1. Redistributions of source code must retain the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer.
|
||||
dnl
|
||||
dnl 2. Redistributions in binary form must reproduce the above copyright
|
||||
dnl notice, this list of conditions and the following disclaimer in
|
||||
dnl the documentation and/or other materials provided with the
|
||||
dnl distribution.
|
||||
dnl
|
||||
dnl THIS SOFTWARE IS PROVIDED BY SASCHA SCHUMANN ``AS IS'' AND ANY
|
||||
dnl EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
dnl IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
dnl PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SASCHA SCHUMANN OR
|
||||
dnl HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
dnl SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
dnl NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
dnl LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
dnl HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
dnl STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
dnl OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
dnl
|
||||
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
|
||||
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
|
||||
*solaris*)
|
||||
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
|
||||
*freebsd*)
|
||||
PTHREAD_FLAGS="-D_REENTRANT -D_THREAD_SAFE";;
|
||||
*linux*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*aix*)
|
||||
PTHREAD_FLAGS=-D_THREAD_SAFE;;
|
||||
*irix*)
|
||||
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
|
||||
*hpux*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*sco*)
|
||||
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
|
||||
|
||||
if test -n "$PTHREAD_FLAGS"; then
|
||||
CPPFLAGS="$CPPFLAGS $PTHREAD_FLAGS"
|
||||
fi
|
||||
])dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK_COMPILE
|
||||
dnl
|
||||
dnl Check whether the current setup can use POSIX threads calls
|
||||
dnl
|
||||
AC_DEFUN(PTHREADS_CHECK_COMPILE, [
|
||||
AC_TRY_RUN( [
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void *thread_routine(void *data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
int main() {
|
||||
pthread_t thd;
|
||||
pthread_mutexattr_t mattr;
|
||||
int data = 1;
|
||||
pthread_mutexattr_init(&mattr);
|
||||
return pthread_create(&thd, NULL, thread_routine, &data);
|
||||
} ], [
|
||||
pthreads_working=yes
|
||||
], [
|
||||
pthreads_working=no
|
||||
], pthreads_working=no ) ] )dnl
|
||||
dnl
|
||||
dnl PTHREADS_CHECK()
|
||||
dnl
|
||||
dnl Try to find a way to enable POSIX threads
|
||||
dnl
|
||||
dnl Magic flags
|
||||
dnl -kthread gcc (FreeBSD)
|
||||
dnl -Kthread UDK cc (UnixWare)
|
||||
dnl -mt WorkShop cc (Solaris)
|
||||
dnl -mthreads gcc (AIX)
|
||||
dnl -pthread gcc (Linux, FreeBSD, NetBSD, OpenBSD)
|
||||
dnl -pthreads gcc (Solaris)
|
||||
dnl -qthreaded AIX cc V5
|
||||
dnl -threads gcc (HP-UX)
|
||||
dnl
|
||||
AC_DEFUN(PTHREADS_CHECK,[
|
||||
|
||||
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_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
|
||||
LIBS="$LIBS -l$lib"
|
||||
PTHREADS_CHECK_COMPILE
|
||||
LIBS=$ac_save
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
ac_cv_pthreads_lib=$lib
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
if test "$pthreads_working" = "yes"; then
|
||||
threads_result="POSIX-Threads found"
|
||||
else
|
||||
threads_result="POSIX-Threads not found"
|
||||
fi
|
||||
])dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(PTHREADS_ASSIGN_VARS,[
|
||||
if test -n "$ac_cv_pthreads_lib"; then
|
||||
LIBS="$LIBS -l$ac_cv_pthreads_lib"
|
||||
fi
|
||||
|
||||
if test -n "$ac_cv_pthreads_cflags"; then
|
||||
CFLAGS="$CFLAGS $ac_cv_pthreads_cflags"
|
||||
fi
|
||||
])dnl
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
|
||||
dnl TSRM_CHECK_GCC_ARG(ARG, ACTION-IF-FOUND, ACTION-IF-NOT_FOUND)
|
||||
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
|
||||
cmd='$CC $1 -c conftest.c'
|
||||
if eval $cmd 2>&1 | egrep -e $1 >/dev/null ; then
|
||||
ac_result=no
|
||||
else
|
||||
ac_result=yes
|
||||
fi
|
||||
eval $gcc_arg_name=$ac_result
|
||||
rm -f conftest.*
|
||||
])
|
||||
if eval test "\$$gcc_arg_name" = "yes"; then
|
||||
$2
|
||||
else
|
||||
:
|
||||
$3
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN(TSRM_BASIC_CHECKS,[
|
||||
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
dnl AC_REQUIRE([AM_PROG_CC_STDC])dnl
|
||||
AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AC_PROG_RANLIB])dnl
|
||||
|
||||
AC_CHECK_HEADERS(stdarg.h)
|
||||
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN(TSRM_CHECK_PTH,[
|
||||
|
||||
AC_MSG_CHECKING(for GNU Pth)
|
||||
PTH_PREFIX="`$1 --prefix`"
|
||||
if test -z "$PTH_PREFIX"; then
|
||||
AC_MSG_RESULT(Please check your Pth installation)
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS `$1 --cflags`"
|
||||
LDFLAGS="$LDFLAGS `$1 --ldflags`"
|
||||
LIBS="$LIBS `$1 --libs`"
|
||||
|
||||
AC_DEFINE(GNUPTH, 1, [Whether you use GNU Pth])
|
||||
AC_MSG_RESULT(yes - installed in $PTH_PREFIX)
|
||||
|
||||
])
|
||||
|
||||
AC_DEFUN(TSRM_CHECK_ST,[
|
||||
if test -r "$1/include/st.h"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$1/include"
|
||||
LDFLAGS="$LDFLAGS -L$1/lib"
|
||||
elif test -r "$1/st.h"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$1"
|
||||
LDFLAGS="$LDFLAGS -L$1"
|
||||
fi
|
||||
AC_CHECK_HEADERS(st.h,[],[
|
||||
AC_MSG_ERROR([Sorry[,] I was unable to locate the State Threads header file. Please specify the prefix using --with-tsrm-st=/prefix])
|
||||
])
|
||||
LIBS="$LIBS -lst"
|
||||
AC_MSG_CHECKING(for SGI's State Threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(TSRM_ST, 1, [ ])
|
||||
])
|
||||
|
||||
sinclude(threads.m4)
|
||||
sinclude(TSRM/threads.m4)
|
||||
|
||||
AC_DEFUN(TSRM_CHECK_PTHREADS,[
|
||||
|
||||
PTHREADS_CHECK
|
||||
|
||||
if test "$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,[
|
||||
|
||||
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.],[
|
||||
TSRM_PTH=$withval
|
||||
],[
|
||||
TSRM_PTH=no
|
||||
])
|
||||
|
||||
AC_ARG_WITH(tsrm-st,
|
||||
[ --with-tsrm-st],[
|
||||
TSRM_ST=$withval
|
||||
],[
|
||||
TSRM_ST=no
|
||||
])
|
||||
|
||||
AC_ARG_WITH(tsrm-pthreads,
|
||||
[ --with-tsrm-pthreads Use POSIX threads (default)],[
|
||||
TSRM_PTHREADS=$withval
|
||||
],[
|
||||
TSRM_PTHREADS=yes
|
||||
])
|
||||
|
||||
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,9 +0,0 @@
|
||||
#ifndef TSRM_CONFIG_NW_H
|
||||
#define TSRM_CONFIG_NW_H
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
|
||||
/* #define HAVE_ALLOCA 1 */
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef TSRM_CONFIG_W32_H
|
||||
#define TSRM_CONFIG_W32_H
|
||||
|
||||
#define HAVE_UTIME 1
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
#undef inline
|
||||
#ifdef ZEND_WIN32_FORCE_INLINE
|
||||
# define inline __forceinline
|
||||
#else
|
||||
# define inline
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef TSRM_CONFIG_COMMON_H
|
||||
#define TSRM_CONFIG_COMMON_H
|
||||
|
||||
#if WINNT|WIN32
|
||||
# define TSRM_WIN32
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# include "tsrm_config.w32.h"
|
||||
#elif defined(NETWARE)
|
||||
# include "tsrm_config.nw.h"
|
||||
#else
|
||||
# include "tsrm_config.h"
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifndef __GNUC__
|
||||
# if HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
# else
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# else
|
||||
# define MAXPATHLEN 256
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2))
|
||||
# define tsrm_do_alloca(p) alloca(p)
|
||||
# define tsrm_free_alloca(p)
|
||||
#else
|
||||
# define tsrm_do_alloca(p) malloc(p)
|
||||
# define tsrm_free_alloca(p) free(p)
|
||||
#endif
|
||||
|
||||
#endif /* TSRM_CONFIG_COMMON_H */
|
||||
-260
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef NETWARE
|
||||
|
||||
#ifdef USE_MKFIFO
|
||||
#include <sys/stat.h>
|
||||
#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */
|
||||
#include <nks/fsio.h>
|
||||
#endif
|
||||
|
||||
#include <nks/vm.h>
|
||||
#include <nks/memory.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mktemp.h"
|
||||
|
||||
/* strtok() call in LibC is abending when used in a different address space -- hence using
|
||||
PHP's version itself for now : Venkat (30/4/02) */
|
||||
#include "tsrm_strtok_r.h"
|
||||
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
|
||||
|
||||
#define WHITESPACE " \t"
|
||||
#define MAX_ARGS 10
|
||||
|
||||
|
||||
TSRM_API FILE* popen(const char *commandline, const char *type)
|
||||
{
|
||||
char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
|
||||
char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
|
||||
char *filePath = NULL;
|
||||
char *ptr = NULL;
|
||||
int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
|
||||
FILE *stream = NULL;
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
int pipe_handle;
|
||||
int mode = O_RDONLY;
|
||||
#else
|
||||
NXHandle_t pipe_handle;
|
||||
NXMode_t mode = NX_O_RDONLY;
|
||||
#endif
|
||||
NXExecEnvSpec_t envSpec;
|
||||
NXNameSpec_t nameSpec;
|
||||
NXVmId_t newVM = 0;
|
||||
|
||||
/* Check for validity of input parameters */
|
||||
if (!commandline || !type)
|
||||
return NULL;
|
||||
|
||||
/* Get temporary file name */
|
||||
filePath = mktemp(tempName);
|
||||
/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/
|
||||
if (!filePath)
|
||||
return NULL;
|
||||
|
||||
/* Set pipe mode according to type -- for now allow only "r" or "w" */
|
||||
if (strcmp(type, "r") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_RDONLY;
|
||||
#else
|
||||
mode = NX_O_RDONLY;
|
||||
#endif
|
||||
else if (strcmp(type, "w") == 0)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
mode = O_WRONLY;
|
||||
#else
|
||||
mode = NX_O_WRONLY;
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
|
||||
#ifdef USE_PIPE_OPEN
|
||||
pipe_handle = pipe_open(filePath, mode);
|
||||
/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#elif defined(USE_MKFIFO)
|
||||
pipe_handle = mkfifo(filePath, mode);
|
||||
consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
|
||||
if (pipe_handle == -1)
|
||||
return NULL;
|
||||
#else
|
||||
/*
|
||||
- NetWare doesn't require first parameter
|
||||
- Allowing LibC to choose the buffer size for now
|
||||
*/
|
||||
err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
|
||||
/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/
|
||||
if (err)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* Copy the environment variables in preparation for the spawn call */
|
||||
|
||||
envCount = NXGetEnvCount() + 1; /* add one for NULL */
|
||||
env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0);
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
err = NXCopyEnv(env, envCount);
|
||||
consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err);
|
||||
if (err)
|
||||
{
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Separate commandline string into words */
|
||||
consoleprintf ("PHP | popen: commandline = %s\n", commandline);
|
||||
ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
command = (char*)malloc(ptrLen + 1);
|
||||
if (!command)
|
||||
{
|
||||
NXMemFree (env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (command, ptr);
|
||||
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
while (ptr && (argc < MAX_ARGS))
|
||||
{
|
||||
ptrLen = strlen(ptr);
|
||||
|
||||
argv[argc] = (char*)malloc(ptrLen + 1);
|
||||
if (!argv[argc])
|
||||
{
|
||||
NXMemFree (env);
|
||||
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (argv[argc], ptr);
|
||||
|
||||
argc++;
|
||||
|
||||
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
|
||||
}
|
||||
consoleprintf ("PHP | popen: commandline string parsed into tokens\n");
|
||||
/* Setup the execution environment and spawn new process */
|
||||
|
||||
envSpec.esFlags = 0; /* Not used */
|
||||
envSpec.esArgc = argc;
|
||||
envSpec.esArgv = (void**)argv;
|
||||
envSpec.esEnv = (void**)env;
|
||||
|
||||
envSpec.esStdin.ssType =
|
||||
envSpec.esStdout.ssType = NX_OBJ_FIFO;
|
||||
envSpec.esStderr.ssType = NX_OBJ_FILE;
|
||||
/*
|
||||
envSpec.esStdin.ssHandle =
|
||||
envSpec.esStdout.ssHandle =
|
||||
envSpec.esStderr.ssHandle = -1;
|
||||
*/
|
||||
envSpec.esStdin.ssPathCtx =
|
||||
envSpec.esStdout.ssPathCtx =
|
||||
envSpec.esStderr.ssPathCtx = NULL;
|
||||
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
if (mode == O_RDONLY)
|
||||
#else
|
||||
if (mode == NX_O_RDONLY)
|
||||
#endif
|
||||
{
|
||||
envSpec.esStdin.ssPath = filePath;
|
||||
envSpec.esStdout.ssPath = stdout;
|
||||
}
|
||||
else /* Write Only */
|
||||
{
|
||||
envSpec.esStdin.ssPath = stdin;
|
||||
envSpec.esStdout.ssPath = filePath;
|
||||
}
|
||||
|
||||
envSpec.esStderr.ssPath = stdout;
|
||||
|
||||
nameSpec.ssType = NX_OBJ_FIFO;
|
||||
/* nameSpec.ssHandle = 0; */ /* Not used */
|
||||
nameSpec.ssPathCtx = NULL; /* Not used */
|
||||
nameSpec.ssPath = argv[0];
|
||||
consoleprintf ("PHP | popen: environment setup\n");
|
||||
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
|
||||
consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err);
|
||||
if (!err)
|
||||
/* Get file pointer corresponding to the pipe (file) opened */
|
||||
stream = fdopen(pipe_handle, type);
|
||||
|
||||
/* Clean-up */
|
||||
|
||||
if (env)
|
||||
NXMemFree (env);
|
||||
|
||||
if (pipe_handle)
|
||||
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
|
||||
close(pipe_handle);
|
||||
#else
|
||||
NXClose(pipe_handle);
|
||||
#endif
|
||||
|
||||
if (command)
|
||||
free (command);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (argv[i])
|
||||
free (argv[i]);
|
||||
}
|
||||
consoleprintf ("PHP | popen: all clean-up done, returning...\n");
|
||||
return stream;
|
||||
}
|
||||
|
||||
TSRM_API int pclose(FILE* stream)
|
||||
{
|
||||
int err = 0;
|
||||
NXHandle_t fd = 0;
|
||||
|
||||
/* Get the process associated with this pipe (file) handle and terminate it */
|
||||
fd = fileno(stream);
|
||||
NXClose (fd);
|
||||
|
||||
err = fclose(stream);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#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
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tsrm_config_common.h"
|
||||
#include "tsrm_strtok_r.h"
|
||||
|
||||
static inline int in_character_class(char ch, const char *delim)
|
||||
{
|
||||
while (*delim) {
|
||||
if (*delim == ch) {
|
||||
return 1;
|
||||
}
|
||||
delim++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *tsrm_strtok_r(char *s, const char *delim, char **last)
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL) {
|
||||
s = *last;
|
||||
}
|
||||
|
||||
while (*s && in_character_class(*s, delim)) {
|
||||
s++;
|
||||
}
|
||||
if (!*s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
token = s;
|
||||
|
||||
while (*s && !in_character_class(*s, delim)) {
|
||||
s++;
|
||||
}
|
||||
if (!*s) {
|
||||
*last = s;
|
||||
} else {
|
||||
*s = '\0';
|
||||
*last = s + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
main()
|
||||
{
|
||||
char foo[] = "/foo/bar//\\barbara";
|
||||
char *last;
|
||||
char *token;
|
||||
|
||||
token = tsrm_strtok_r(foo, "/\\", &last);
|
||||
while (token) {
|
||||
printf ("Token = '%s'\n", token);
|
||||
token = tsrm_strtok_r(NULL, "/\\", &last);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef TSRM_STRTOK_R
|
||||
#define TSRM_STRTOK_R
|
||||
|
||||
char *tsrm_strtok_r(char *s, const char *delim, char **last);
|
||||
|
||||
#endif
|
||||
@@ -1,864 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "tsrm_virtual_cwd.h"
|
||||
#include "tsrm_strtok_r.h"
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <io.h>
|
||||
#include "tsrm_win32.h"
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
/*#include "pipe.h"*/
|
||||
#include "tsrm_nw.h"
|
||||
#endif
|
||||
|
||||
#define VIRTUAL_CWD_DEBUG 0
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
/* Only need mutex for popen() in Windows and NetWare, because it doesn't chdir() on UNIX */
|
||||
#if (defined(TSRM_WIN32) || defined(NETWARE)) && defined(ZTS)
|
||||
MUTEX_T cwd_mutex;
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
static ts_rsrc_id cwd_globals_id;
|
||||
#else
|
||||
static virtual_cwd_globals cwd_globals;
|
||||
#endif
|
||||
|
||||
cwd_state main_cwd_state; /* True global */
|
||||
|
||||
#ifndef TSRM_WIN32
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(mode) ((mode) & _S_IFREG)
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <tchar.h>
|
||||
#define tsrm_strtok_r(a,b,c) _tcstok((a),(b))
|
||||
#define TOKENIZER_STRING "/\\"
|
||||
|
||||
static int php_check_dots(const char *element, int n)
|
||||
{
|
||||
while (n-- > 0) if (element[n] != '.') break;
|
||||
|
||||
return (n != -1);
|
||||
}
|
||||
|
||||
#define IS_DIRECTORY_UP(element, len) \
|
||||
(len >= 2 && !php_check_dots(element, len))
|
||||
|
||||
#define IS_DIRECTORY_CURRENT(element, len) \
|
||||
(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 "/"
|
||||
#endif
|
||||
|
||||
|
||||
/* default macros */
|
||||
|
||||
#ifndef IS_DIRECTORY_UP
|
||||
#define IS_DIRECTORY_UP(element, len) \
|
||||
(len == 2 && memcmp(element, "..", 2) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef IS_DIRECTORY_CURRENT
|
||||
#define IS_DIRECTORY_CURRENT(element, len) \
|
||||
(len == 1 && ptr[0] == '.')
|
||||
#endif
|
||||
|
||||
/* define this to check semantics */
|
||||
#define IS_DIR_OK(s) (1)
|
||||
|
||||
#ifndef IS_DIR_OK
|
||||
#define IS_DIR_OK(state) (php_is_dir_ok(state) == 0)
|
||||
#endif
|
||||
|
||||
|
||||
#define CWD_STATE_COPY(d, s) \
|
||||
(d)->cwd_length = (s)->cwd_length; \
|
||||
(d)->cwd = (char *) malloc((s)->cwd_length+1); \
|
||||
memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1);
|
||||
|
||||
#define CWD_STATE_FREE(s) \
|
||||
free((s)->cwd);
|
||||
|
||||
static int php_is_dir_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISDIR(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISDIR(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int php_is_file_ok(const cwd_state *state)
|
||||
{
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
struct stat buf;
|
||||
|
||||
if (stat(state->cwd, &buf) == 0 && S_ISREG(buf.st_mode))
|
||||
#else
|
||||
struct stat_libc buf;
|
||||
|
||||
if (stat(state->cwd, (struct stat*)(&buf)) == 0 && S_ISREG(buf.st_mode))
|
||||
#endif
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
|
||||
}
|
||||
|
||||
static void cwd_globals_dtor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
|
||||
{
|
||||
CWD_STATE_FREE(&cwd_globals->cwd);
|
||||
}
|
||||
|
||||
static char *tsrm_strndup(const char *s, size_t length)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = (char *) malloc(length+1);
|
||||
if (!p) {
|
||||
return (char *)NULL;
|
||||
}
|
||||
if (length) {
|
||||
memcpy(p,s,length);
|
||||
}
|
||||
p[length]=0;
|
||||
return p;
|
||||
}
|
||||
|
||||
CWD_API void virtual_cwd_startup(void)
|
||||
{
|
||||
char cwd[MAXPATHLEN];
|
||||
char *result;
|
||||
|
||||
result = getcwd(cwd, sizeof(cwd));
|
||||
if (!result) {
|
||||
cwd[0] = '\0';
|
||||
}
|
||||
main_cwd_state.cwd = strdup(cwd);
|
||||
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);
|
||||
#else
|
||||
cwd_globals_ctor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
|
||||
#if defined(TSRM_WIN32) && defined(ZTS)
|
||||
cwd_mutex = tsrm_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
CWD_API void virtual_cwd_shutdown(void)
|
||||
{
|
||||
#ifndef ZTS
|
||||
cwd_globals_dtor(&cwd_globals TSRMLS_CC);
|
||||
#endif
|
||||
#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_state *state;
|
||||
|
||||
state = &CWDG(cwd);
|
||||
|
||||
if (state->cwd_length == 0) {
|
||||
char *retval;
|
||||
|
||||
*length = 1;
|
||||
retval = (char *) malloc(2);
|
||||
retval[0] = DEFAULT_SLASH;
|
||||
retval[1] = '\0';
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
/* If we have something like C: */
|
||||
if (state->cwd_length == 2 && state->cwd[state->cwd_length-1] == ':') {
|
||||
char *retval;
|
||||
|
||||
*length = state->cwd_length+1;
|
||||
retval = (char *) malloc(*length+1);
|
||||
memcpy(retval, state->cwd, *length);
|
||||
retval[*length-1] = DEFAULT_SLASH;
|
||||
retval[*length] = '\0';
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
*length = state->cwd_length;
|
||||
return strdup(state->cwd);
|
||||
}
|
||||
|
||||
|
||||
/* Same semantics as UNIX getcwd() */
|
||||
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC)
|
||||
{
|
||||
size_t length;
|
||||
char *cwd;
|
||||
|
||||
cwd = virtual_getcwd_ex(&length TSRMLS_CC);
|
||||
|
||||
if (buf == NULL) {
|
||||
return cwd;
|
||||
}
|
||||
if (length > size-1) {
|
||||
free(cwd);
|
||||
errno = ERANGE; /* Is this OK? */
|
||||
return NULL;
|
||||
}
|
||||
memcpy(buf, cwd, length+1);
|
||||
free(cwd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* 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 path_length = strlen(path);
|
||||
char *ptr, *path_copy;
|
||||
char *tok = NULL;
|
||||
int ptr_length;
|
||||
cwd_state *old_state;
|
||||
int ret = 0;
|
||||
int copy_amount = -1;
|
||||
char *free_path;
|
||||
unsigned char is_absolute = 0;
|
||||
#ifndef TSRM_WIN32
|
||||
char resolved_path[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
if (path_length == 0)
|
||||
return (0);
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(__BEOS__) && !defined(NETWARE)
|
||||
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;
|
||||
char *ptr;
|
||||
|
||||
ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
|
||||
if (!tmp) {
|
||||
return 1;
|
||||
}
|
||||
memcpy(ptr, state->cwd, state->cwd_length);
|
||||
ptr += state->cwd_length;
|
||||
*ptr++ = DEFAULT_SLASH;
|
||||
memcpy(ptr, path, path_length);
|
||||
ptr += path_length;
|
||||
*ptr = '\0';
|
||||
if (realpath(tmp, resolved_path)) {
|
||||
path = resolved_path;
|
||||
path_length = strlen(path);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
free_path = path_copy = tsrm_strndup(path, path_length);
|
||||
|
||||
old_state = (cwd_state *) malloc(sizeof(cwd_state));
|
||||
CWD_STATE_COPY(old_state, state);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf(stderr,"cwd = %s path = %s\n", state->cwd, path);
|
||||
#endif
|
||||
if (IS_ABSOLUTE_PATH(path_copy, path_length)) {
|
||||
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
|
||||
#ifndef NETWARE
|
||||
copy_amount = COPY_WHEN_ABSOLUTE;
|
||||
#else
|
||||
copy_amount = COPY_WHEN_ABSOLUTE(path_copy);
|
||||
#endif
|
||||
is_absolute = 1;
|
||||
#ifdef TSRM_WIN32
|
||||
} else if (IS_UNC_PATH(path_copy, path_length)) {
|
||||
copy_amount = 2;
|
||||
is_absolute = 1;
|
||||
} else if (IS_SLASH(path_copy[0])) {
|
||||
copy_amount = 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (copy_amount != -1) {
|
||||
state->cwd = (char *) realloc(state->cwd, copy_amount + 1);
|
||||
if (copy_amount) {
|
||||
if (is_absolute) {
|
||||
memcpy(state->cwd, path_copy, copy_amount);
|
||||
path_copy += copy_amount;
|
||||
} else {
|
||||
memcpy(state->cwd, old_state->cwd, copy_amount);
|
||||
}
|
||||
}
|
||||
state->cwd[copy_amount] = '\0';
|
||||
state->cwd_length = copy_amount;
|
||||
}
|
||||
|
||||
|
||||
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
|
||||
while (ptr) {
|
||||
ptr_length = strlen(ptr);
|
||||
|
||||
if (IS_DIRECTORY_UP(ptr, ptr_length)) {
|
||||
char save;
|
||||
|
||||
save = DEFAULT_SLASH;
|
||||
|
||||
#define PREVIOUS state->cwd[state->cwd_length - 1]
|
||||
|
||||
while (IS_ABSOLUTE_PATH(state->cwd, state->cwd_length) &&
|
||||
!IS_SLASH(PREVIOUS)) {
|
||||
save = PREVIOUS;
|
||||
PREVIOUS = '\0';
|
||||
state->cwd_length--;
|
||||
}
|
||||
|
||||
if (!IS_ABSOLUTE_PATH(state->cwd, state->cwd_length)) {
|
||||
state->cwd[state->cwd_length++] = save;
|
||||
state->cwd[state->cwd_length] = '\0';
|
||||
} else {
|
||||
PREVIOUS = '\0';
|
||||
state->cwd_length--;
|
||||
}
|
||||
} else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
|
||||
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
|
||||
#ifdef TSRM_WIN32
|
||||
/* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
|
||||
if ((state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') ||
|
||||
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#elif defined(NETWARE)
|
||||
/* If the token is a volume name, it will have colon at the end -- so, no slash before it */
|
||||
if (ptr[ptr_length-1] != ':') {
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
}
|
||||
#else
|
||||
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
|
||||
#endif
|
||||
memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
|
||||
state->cwd_length += ptr_length;
|
||||
}
|
||||
ptr = tsrm_strtok_r(NULL, TOKENIZER_STRING, &tok);
|
||||
}
|
||||
|
||||
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
|
||||
#ifndef NETWARE
|
||||
if (state->cwd_length == COPY_WHEN_ABSOLUTE) {
|
||||
#else
|
||||
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
|
||||
#endif
|
||||
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)) {
|
||||
CWD_STATE_FREE(state);
|
||||
|
||||
*state = *old_state;
|
||||
|
||||
ret = 1;
|
||||
} else {
|
||||
CWD_STATE_FREE(old_state);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
free(old_state);
|
||||
|
||||
free(free_path);
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "virtual_file_ex() = %s\n",state->cwd);
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
|
||||
CWD_API int virtual_chdir(const char *path TSRMLS_DC)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int length = strlen(path);
|
||||
char *temp;
|
||||
int retval;
|
||||
|
||||
if (length == 0) {
|
||||
return 1; /* Can't cd to empty string */
|
||||
}
|
||||
while(--length >= 0 && !IS_SLASH(path[length])) {
|
||||
}
|
||||
|
||||
if (length == -1) {
|
||||
/* No directory only file name */
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* COPY_WHEN_ABSOLUTE needs to account for volume name that is unique to NetWare absolute paths */
|
||||
#ifndef NETWARE
|
||||
if (length == COPY_WHEN_ABSOLUTE && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
|
||||
#else
|
||||
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
|
||||
#endif
|
||||
length++;
|
||||
}
|
||||
temp = (char *) tsrm_do_alloca(length+1);
|
||||
memcpy(temp, path, length);
|
||||
temp[length] = 0;
|
||||
#if VIRTUAL_CWD_DEBUG
|
||||
fprintf (stderr, "Changing directory to %s\n", temp);
|
||||
#endif
|
||||
retval = p_chdir(temp TSRMLS_CC);
|
||||
tsrm_free_alloca(temp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
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_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
retval = virtual_file_ex(&new_state, path, verify_path);
|
||||
|
||||
*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_state new_state;
|
||||
FILE *f;
|
||||
|
||||
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);
|
||||
|
||||
f = fopen(new_state.cwd, mode);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return f;
|
||||
}
|
||||
|
||||
#if HAVE_UTIME
|
||||
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, filename, NULL);
|
||||
|
||||
ret = utime(new_state.cwd, buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, filename, NULL);
|
||||
|
||||
ret = chmod(new_state.cwd, mode);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int ret;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, filename, NULL);
|
||||
|
||||
ret = chown(new_state.cwd, owner, group);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int f;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
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);
|
||||
va_end(arg);
|
||||
|
||||
f = open(new_state.cwd, flags, mode);
|
||||
} else {
|
||||
f = open(new_state.cwd, flags);
|
||||
}
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return f;
|
||||
}
|
||||
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int f;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL);
|
||||
|
||||
f = creat(new_state.cwd, mode);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
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);
|
||||
oldname = old_state.cwd;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, newname, NULL);
|
||||
newname = new_state.cwd;
|
||||
|
||||
retval = rename(oldname, newname);
|
||||
|
||||
CWD_STATE_FREE(&old_state);
|
||||
CWD_STATE_FREE(&new_state);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL);
|
||||
|
||||
retval = stat(new_state.cwd, buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL);
|
||||
|
||||
retval = stat(new_state.cwd, (struct stat*)buf);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL);
|
||||
|
||||
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_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, path, NULL);
|
||||
|
||||
retval = unlink(new_state.cwd);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, pathname, NULL);
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
retval = mkdir(new_state.cwd);
|
||||
#else
|
||||
retval = mkdir(new_state.cwd, mode);
|
||||
#endif
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
int retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, pathname, NULL);
|
||||
|
||||
retval = rmdir(new_state.cwd);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
DIR *opendir(const char *name);
|
||||
#endif
|
||||
|
||||
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC)
|
||||
{
|
||||
cwd_state new_state;
|
||||
DIR *retval;
|
||||
|
||||
CWD_STATE_COPY(&new_state, &CWDG(cwd));
|
||||
virtual_file_ex(&new_state, pathname, NULL);
|
||||
|
||||
retval = opendir(new_state.cwd);
|
||||
|
||||
CWD_STATE_FREE(&new_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
|
||||
/* 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 TSRMLS_DC)
|
||||
{
|
||||
char prev_cwd[MAXPATHLEN];
|
||||
char *getcwd_result;
|
||||
FILE *retval;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
int command_length;
|
||||
char *command_line;
|
||||
char *ptr;
|
||||
FILE *retval;
|
||||
|
||||
command_length = strlen(command);
|
||||
|
||||
ptr = command_line = (char *) malloc(command_length + sizeof("cd ; ") + CWDG(cwd).cwd_length+1);
|
||||
if (!command_line) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(ptr, "cd ", sizeof("cd ")-1);
|
||||
ptr += sizeof("cd ")-1;
|
||||
|
||||
if (CWDG(cwd).cwd_length == 0) {
|
||||
*ptr++ = DEFAULT_SLASH;
|
||||
} else {
|
||||
memcpy(ptr, CWDG(cwd).cwd, CWDG(cwd).cwd_length);
|
||||
ptr += CWDG(cwd).cwd_length;
|
||||
}
|
||||
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = ';';
|
||||
*ptr++ = ' ';
|
||||
|
||||
memcpy(ptr, command, command_length+1);
|
||||
retval = popen(command_line, type);
|
||||
|
||||
free(command_line);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Sascha Schumann <sascha@schumann.cx> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef VIRTUAL_CWD_H
|
||||
#define VIRTUAL_CWD_H
|
||||
|
||||
#include "TSRM.h"
|
||||
#include "tsrm_config_common.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#ifndef TSRM_WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include "readdir.h"
|
||||
#include <sys/utime.h>
|
||||
/* mode_t isn't defined on Windows */
|
||||
typedef unsigned short 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))))
|
||||
#define COPY_WHEN_ABSOLUTE 2
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(len >= 2 && isalpha(path[0]) && path[1] == ':')
|
||||
#define IS_UNC_PATH(path, len) \
|
||||
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
|
||||
|
||||
#elif defined(NETWARE)
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SLASH '/'
|
||||
#define DEFAULT_DIR_SEPARATOR ';'
|
||||
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
|
||||
#define COPY_WHEN_ABSOLUTE(path) \
|
||||
(strchr(path, ':') - path + 1) /* Take the volume name which ends with a colon */
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(strchr(path, ':') != NULL) /* Colon indicates volume name */
|
||||
|
||||
#else
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#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 0
|
||||
#endif
|
||||
|
||||
#ifndef IS_ABSOLUTE_PATH
|
||||
#define IS_ABSOLUTE_PATH(path, len) \
|
||||
(IS_SLASH(path[0]))
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_EXPORTS
|
||||
#define CWD_EXPORTS
|
||||
#endif
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
# ifdef CWD_EXPORTS
|
||||
# define CWD_API __declspec(dllexport)
|
||||
# else
|
||||
# define CWD_API __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
#define CWD_API
|
||||
#endif
|
||||
|
||||
typedef struct _cwd_state {
|
||||
char *cwd;
|
||||
int cwd_length;
|
||||
} cwd_state;
|
||||
|
||||
typedef int (*verify_path_func)(const cwd_state *);
|
||||
|
||||
CWD_API void virtual_cwd_startup(void);
|
||||
CWD_API void virtual_cwd_shutdown(void);
|
||||
CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
|
||||
CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC);
|
||||
CWD_API int virtual_chdir(const char *path TSRMLS_DC);
|
||||
CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path TSRMLS_DC) TSRMLS_DC);
|
||||
CWD_API int virtual_filepath(const char *path, char **filepath TSRMLS_DC);
|
||||
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC);
|
||||
CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC);
|
||||
CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC);
|
||||
CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...);
|
||||
CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC);
|
||||
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
|
||||
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#else
|
||||
CWD_API int virtual_stat(const char *path, struct stat_libc *buf TSRMLS_DC);
|
||||
#endif
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
|
||||
#endif
|
||||
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
|
||||
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
|
||||
CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC);
|
||||
CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC);
|
||||
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC);
|
||||
#if HAVE_UTIME
|
||||
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);
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group TSRMLS_DC);
|
||||
#endif
|
||||
|
||||
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)
|
||||
#else
|
||||
# define CWDG(v) (cwd_globals.v)
|
||||
#endif
|
||||
|
||||
/* The actual macros to be used in programs using TSRM
|
||||
* If the program defines VIRTUAL_DIR it will use the
|
||||
* virtual_* functions
|
||||
*/
|
||||
|
||||
#ifdef VIRTUAL_DIR
|
||||
|
||||
#define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
|
||||
#define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
|
||||
/* Because open() has two modes, we have to macros to replace it */
|
||||
#define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
|
||||
#define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
|
||||
#define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
|
||||
#define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
|
||||
#define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
|
||||
#define VCWD_GETWD(buf)
|
||||
#define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
|
||||
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
|
||||
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
#if !defined(TSRM_WIN32) && !defined(NETWARE)
|
||||
#define VCWD_LSTAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
|
||||
#else
|
||||
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
|
||||
#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)
|
||||
#if HAVE_UTIME
|
||||
#define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
|
||||
#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) && !defined(NETWARE)
|
||||
#define VCWD_REALPATH(path, real_path) realpath(path, real_path)
|
||||
#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)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* VIRTUAL_CWD_H */
|
||||
@@ -1,359 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Daniel Beulshausen <daniel@php4win.de> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#include <windows.h>
|
||||
#include "tsrm_win32.h"
|
||||
|
||||
#ifdef ZTS
|
||||
static ts_rsrc_id win32_globals_id;
|
||||
#else
|
||||
static tsrm_win32_globals win32_globals;
|
||||
#endif
|
||||
|
||||
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
globals->process = NULL;
|
||||
globals->shm = NULL;
|
||||
globals->process_size = 0;
|
||||
globals->shm_size = 0;
|
||||
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
|
||||
}
|
||||
|
||||
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
|
||||
{
|
||||
shm_pair *ptr;
|
||||
|
||||
if (globals->process) {
|
||||
free(globals->process);
|
||||
}
|
||||
|
||||
if (globals->shm) {
|
||||
for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
|
||||
UnmapViewOfFile(ptr->addr);
|
||||
CloseHandle(ptr->segment);
|
||||
UnmapViewOfFile(ptr->descriptor);
|
||||
CloseHandle(ptr->info);
|
||||
}
|
||||
free(globals->shm);
|
||||
}
|
||||
|
||||
free(globals->comspec);
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_startup(void)
|
||||
{
|
||||
#ifdef ZTS
|
||||
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
|
||||
#else
|
||||
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
TSRM_API void tsrm_win32_shutdown(void)
|
||||
{
|
||||
#ifndef ZTS
|
||||
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
|
||||
#endif
|
||||
}
|
||||
|
||||
static process_pair *process_get(FILE *stream TSRMLS_DC)
|
||||
{
|
||||
process_pair *ptr;
|
||||
process_pair *newptr;
|
||||
|
||||
for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
|
||||
if (ptr->stream == stream) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr < (TWG(process) + TWG(process_size))) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
|
||||
if (newptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TWG(process) = newptr;
|
||||
ptr = newptr + TWG(process_size);
|
||||
TWG(process_size)++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static shm_pair *shm_get(int key, void *addr)
|
||||
{
|
||||
shm_pair *ptr;
|
||||
shm_pair *newptr;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
|
||||
if (!ptr->descriptor) {
|
||||
continue;
|
||||
}
|
||||
if (!addr && ptr->descriptor->shm_perm.key == key) {
|
||||
break;
|
||||
} else if (ptr->addr == addr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr < (TWG(shm) + TWG(shm_size))) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
|
||||
if (newptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TWG(shm) = newptr;
|
||||
ptr = newptr + TWG(shm_size);
|
||||
TWG(shm_size)++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
|
||||
HANDLE copy, self = GetCurrentProcess();
|
||||
if (!DuplicateHandle(self, fh, self, ©, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
TSRM_API FILE *popen(const char *command, const char *type)
|
||||
{
|
||||
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, NULL, NULL, &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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 4 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2002 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.02 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.php.net/license/2_02.txt. |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Daniel Beulshausen <daniel@php4win.de> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef TSRM_WIN32_H
|
||||
#define TSRM_WIN32_H
|
||||
|
||||
#include "TSRM.h"
|
||||
|
||||
#ifdef TSRM_WIN32
|
||||
#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
|
||||
|
||||
#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(const char *command, const char *type);
|
||||
TSRM_API int pclose(FILE *stream);
|
||||
|
||||
TSRM_API int shmget(int key, int size, int flags);
|
||||
TSRM_API void *shmat(int key, const void *shmaddr, int flags);
|
||||
TSRM_API int shmdt(const void *shmaddr);
|
||||
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
- Persistant per-process scripting
|
||||
|
||||
Apache 1.3 has added things that makes this much easier than before.
|
||||
The module structure now contains a child_init hook and a child_exit
|
||||
hook where you can register functions to be called when an httpd
|
||||
process starts up and when one shuts down (due to MaxRequestsPerChild
|
||||
or a Kill). The only real trick now is to come up with some sort of
|
||||
syntax for specifying what to do from the child_init call and the
|
||||
child_exit call.
|
||||
|
||||
One idea is to be able to add a <PHP>...</PHP> block to the Apache
|
||||
httpd.conf file which would somehow define a series of PHP statements
|
||||
to be executed from the child_* calls. One for startup and another
|
||||
block for shutdown. These blocks would work with the per-process
|
||||
memory pool, so any variables initialized here would have a lifespan
|
||||
equal to that of the httpd process. Basically request-spanning
|
||||
global variables.
|
||||
@@ -0,0 +1,55 @@
|
||||
V Do yystype_ptr and hash pointers the right way - use the hash
|
||||
pointer and the bucket pointer, instead of a pointer to the data.
|
||||
Allows for a real unset() among other things.
|
||||
V Improve performance of simple variable lookups
|
||||
* Improve string performance by using smarter memory allocation methods
|
||||
- Improve preprocessor (handle require() efficiently), possibly handle
|
||||
automatic preprocessing for sites based on timestamp
|
||||
V Use a reference count mechanism to prevent unnecessary duplication of data.
|
||||
* Write and stabilize a complete persistent data API. Feature wishlist:
|
||||
- memory manager using shared memory
|
||||
- process-global symbol table
|
||||
- make api inter-thread capable for win32 and some far off future where unix
|
||||
version will be multithreaded
|
||||
V Handle out of memory (inside emalloc()?)
|
||||
* Try to figure out a way to declare *real* global variables
|
||||
* Improve the reading of configuration variables into php3_ini (generalize)
|
||||
Make it possible to implement config_get("configuration_variable") and
|
||||
config_set("configuration_variable","value") that'll work with *php3_ini*,
|
||||
not the configuration hash!
|
||||
* Bundle some nice classes (like Bjørn's graphing class)
|
||||
* Bundle some database abstraction classes
|
||||
* Distribute binaries
|
||||
* Clean up API and modules to make .so modules portable across CGI and server
|
||||
binaries
|
||||
* dbm cleanup (don't arbitrarily pick, and support multiple concurrent formats)
|
||||
* start system defines so that we can move away from the standard c lib on
|
||||
windows to the win32 lib. (file functions primarily)
|
||||
* COM implementation so php can be used as an asp language (cant find any docs
|
||||
on how this is done though)
|
||||
* Clean up the file structure so the top-level directory isn't such a mess.
|
||||
* Bring the module concept to maturity: use libtool and make it
|
||||
possible to decide at compile time whether you want to compile a
|
||||
module statically or dynamically. Remove the distinction between
|
||||
the stuff currently in dl/ and functions/.
|
||||
* a way of letting each module specify its options, so ini file options and
|
||||
Apache directives can be set up from the same specification.
|
||||
V Make it possible to declare smarter user functions: (done in 3.0)
|
||||
- Optional parameters
|
||||
- Parameters that are forced/prefered by reference
|
||||
* Make object parsing more general, and allow nested arrays/objects with
|
||||
unlimited levels.
|
||||
V Make it possible to copy references of variables.
|
||||
* data tainting (like perl -T)
|
||||
* multi-dimensional array support in GET/POST/COOKIE handling code
|
||||
* Persistent functions and classes
|
||||
* odbc_fetch_assoc
|
||||
* Add env handling to gpc_order
|
||||
* Populate track_vars regardless of gpc_order
|
||||
* a real exec() function
|
||||
* Support passing arguments to functions by name (e.g. foo(arg1 => "bar", arg2 => "foobar"))
|
||||
* Add an optional setting to destroy persistent resources if a PHP script terminates
|
||||
abnormally
|
||||
V COM automation support for Win32
|
||||
? Add a setting for making function names case sensitive
|
||||
* stat() files before feeding them to flex - it doesn't handle special files very well
|
||||
@@ -0,0 +1,37 @@
|
||||
Zend Temporary License
|
||||
======================
|
||||
|
||||
This is a temporary license, that is in effect until the final Zend license
|
||||
is available.
|
||||
|
||||
* The final license will include the ability to distribute Zend freely,
|
||||
as a part of PHP (in both compiled and source code formats). It may
|
||||
(and probably will) allow to redistribute Zend under other circumstances
|
||||
as well, but at the very least, it'll be freely distributed as a part
|
||||
of PHP.
|
||||
|
||||
* The source code in the Zend engine is the property of Andi Gutmans and
|
||||
Zeev Suraski. Parts of this code are based on source code taken from
|
||||
PHP 3.0, which may include several patches and enhancements that weren't
|
||||
made by us (Andi&Zeev). If you're the author of such a patch and you're
|
||||
not willing to give up ownership over your patch to us, please contact
|
||||
us as soon as possible, so we can remove it. We're doing this so that
|
||||
we'd be eligible to sell the Zend engine for uses other than PHP, most
|
||||
notably - as an embedded part of possible commercial products that we'd
|
||||
have.
|
||||
|
||||
* Patches submitted to the Zend CVS automatically fall under this license,
|
||||
and by submitting them you're implicitly giving up your ownership over
|
||||
this patch to us.
|
||||
|
||||
* Until further notice, Zend is in a status of a closed beta test. That means
|
||||
that only people that were explicitly given the right to access the Zend
|
||||
CVS repository are allowed to use it. If you're reading this file and you
|
||||
weren't explicitly given the right to access the Zend CVS repository from
|
||||
either Andi Gutmans or Zeev Suraski - you're not supposed to have it - please
|
||||
erase the Zend files from your system. When the closed beta period finishes,
|
||||
the Zend CVS tree will be open for the public (in read-only mode, of course).
|
||||
|
||||
|
||||
Any questions regarding Zend or this license should be addressed via Email to
|
||||
zend@zend.com.
|
||||
@@ -0,0 +1,145 @@
|
||||
CC = @CC@
|
||||
AR = ar rc
|
||||
LIBNAME = libzend.a
|
||||
PROF_CFLAGS =
|
||||
CFLAGS_SHLIB = @CFLAGS_SHLIB@
|
||||
LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
|
||||
LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@ $(CFLAGS_SHLIB) $(CPPFLAGS) $(INCLUDE) @DEBUG_CFLAGS@ $(PROF_CFLAGS)
|
||||
LDFLAGS = @LDFLAGS@ $(LDFLAGS_SHLIB) $(LDFLAGS_SHLIB_EXPORT)
|
||||
RANLIB = @RANLIB@
|
||||
YACC = @YACC@
|
||||
|
||||
SOURCE = zend_alloc.c zend_compile.c zend_constants.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-parser.c zend-scanner.c zend.c zend_API.c zend_extensions.c \
|
||||
zend_hash.c zend_list.c zend_indent.c
|
||||
|
||||
OBJS = zend_alloc.o zend_compile.o zend_constants.o zend_execute.o zend_execute_API.o \
|
||||
zend_highlight.o zend_llist.o zend_opcode.o zend_operators.o zend_ptr_stack.o \
|
||||
zend_stack.o zend_variables.o zend-parser.o zend-scanner.o zend.o zend_API.o zend_extensions.o \
|
||||
zend_hash.o zend_list.o zend_indent.o
|
||||
|
||||
LIBS = @LIBS@
|
||||
|
||||
all: $(LIBNAME)
|
||||
|
||||
libzend.a: $(OBJS)
|
||||
-rm -f libzend.a
|
||||
$(AR) libzend.a $(OBJS)
|
||||
$(RANLIB) libzend.a
|
||||
|
||||
zend-parser.h zend-parser.c: zend-parser.y
|
||||
bison -p zend -v -d zend-parser.y -o zend-parser.c
|
||||
|
||||
zend-scanner.o:
|
||||
$(CC) $(CFLAGS) -w -c zend-scanner.c
|
||||
|
||||
zend-scanner.c: zend-scanner.l
|
||||
flex -Pzend -ozend-scanner.c -i zend-scanner.l
|
||||
|
||||
clean:
|
||||
-rm -f libzend.a *.o
|
||||
|
||||
distclean: clean
|
||||
-rm -f *-scanner.c *-parser.[ch] *.output
|
||||
-rm -f config.status config.cache config.log
|
||||
-rm -f Makefile Makefile.depend config.h
|
||||
|
||||
.c.o:
|
||||
@rm -f $@
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@bn=`echo $@ | sed -e 's#functions/##'`; test -f $@ || \
|
||||
(test "$@" != "$$bn" && test -f "$$bn" && mv $$bn $@)
|
||||
|
||||
parser-scanner: zend-parser.c zend-parser.h zend-scanner.c
|
||||
|
||||
depend: parser-scanner
|
||||
$(CC) $(CFLAGS) -MM $(SOURCE) | perl -pe 's|regex/regex.h||;' > Makefile.depend
|
||||
|
||||
|
||||
zend_alloc.o: zend_alloc.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h zend_globals.h zend_stack.h \
|
||||
zend_ptr_stack.h zend_compile.h zend-parser.h zend_execute.h
|
||||
zend_compile.o: zend_compile.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_API.h modules.h zend_list.h zend_variables.h \
|
||||
zend_operators.h
|
||||
zend_constants.o: zend_constants.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_constants.h \
|
||||
zend_variables.h zend_operators.h zend_globals.h zend_stack.h \
|
||||
zend_ptr_stack.h zend_compile.h zend-parser.h zend_execute.h
|
||||
zend_execute.o: zend_execute.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_API.h modules.h zend_list.h zend_variables.h \
|
||||
zend_operators.h zend_constants.h zend_extensions.h
|
||||
zend_execute_API.o: zend_execute_API.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_API.h modules.h zend_list.h zend_variables.h \
|
||||
zend_operators.h zend_constants.h zend_extensions.h
|
||||
zend_highlight.o: zend_highlight.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_highlight.h
|
||||
zend_llist.o: zend_llist.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h
|
||||
zend_opcode.o: zend_opcode.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_variables.h zend_operators.h zend_extensions.h \
|
||||
zend_API.h modules.h zend_list.h
|
||||
zend_operators.o: zend_operators.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_operators.h \
|
||||
zend_variables.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_compile.h zend-parser.h zend_execute.h
|
||||
zend_ptr_stack.o: zend_ptr_stack.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_ptr_stack.h
|
||||
zend_stack.o: zend_stack.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h zend_stack.h
|
||||
zend_variables.o: zend_variables.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_API.h \
|
||||
modules.h zend_list.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_compile.h zend-parser.h zend_execute.h zend_constants.h \
|
||||
zend_variables.h
|
||||
zend-parser.o: zend-parser.c zend_compile.h zend.h config.h \
|
||||
config.unix.h zend_errors.h zend_alloc.h zend_hash.h zend_llist.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_list.h zend_API.h modules.h zend_variables.h \
|
||||
zend_operators.h
|
||||
zend-scanner.o: zend-scanner.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend-scanner.h zend_highlight.h zend_constants.h \
|
||||
zend_variables.h zend_operators.h
|
||||
zend.o: zend.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h zend_operators.h \
|
||||
zend_variables.h zend_extensions.h zend_compile.h zend-parser.h \
|
||||
zend_globals.h zend_stack.h zend_ptr_stack.h zend_execute.h modules.h \
|
||||
zend_constants.h zend_list.h
|
||||
zend_API.o: zend_API.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h zend_variables.h zend_execute.h \
|
||||
zend_compile.h zend-parser.h zend_globals.h zend_stack.h \
|
||||
zend_ptr_stack.h zend_API.h modules.h zend_list.h zend_constants.h \
|
||||
zend_operators.h
|
||||
zend_extensions.o: zend_extensions.c zend_extensions.h zend_compile.h \
|
||||
zend.h config.h config.unix.h zend_errors.h zend_alloc.h zend_hash.h \
|
||||
zend_llist.h zend-parser.h zend_globals.h zend_stack.h \
|
||||
zend_ptr_stack.h zend_execute.h
|
||||
zend_hash.o: zend_hash.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h
|
||||
zend_list.o: zend_list.c zend.h config.h config.unix.h zend_errors.h \
|
||||
zend_alloc.h zend_hash.h zend_llist.h zend_list.h zend_API.h \
|
||||
modules.h zend_globals.h zend_stack.h zend_ptr_stack.h zend_compile.h \
|
||||
zend-parser.h zend_execute.h
|
||||
zend_indent.o: zend_indent.c zend.h config.h config.unix.h \
|
||||
zend_errors.h zend_alloc.h zend_hash.h zend_llist.h zend_compile.h \
|
||||
zend-parser.h zend_globals.h zend_stack.h zend_ptr_stack.h \
|
||||
zend_execute.h zend_indent.h
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 4
|
||||
# End:
|
||||
@@ -0,0 +1,111 @@
|
||||
Improvements
|
||||
------------
|
||||
|
||||
Zend was designed from the ground up for increased speed,
|
||||
reduced memory consumption and more reliable execution. We dare
|
||||
say it meets all of these goals and does so pretty well. Beyond
|
||||
that, there are several improvements in the language engine
|
||||
features:
|
||||
|
||||
* References support. $foo = &$a; would make $foo and $a be two
|
||||
names to the same variable. This works with arrays as well,
|
||||
on either side; e.g., $foo = &$a[7]; would make $foo and $a[7]
|
||||
be two names to the same variable. Changing one would change
|
||||
the other and vice versa.
|
||||
* Object overloading support. This feature allows various OO
|
||||
libraries to use the OO notation of PHP to access their
|
||||
functionality. Right now, no use is made of that feature,
|
||||
but we'd have a COM module ready by the time PHP 4.0 is released.
|
||||
A CORBA module would probably follow.
|
||||
* include() and eval() are now functions, and not statements.
|
||||
That means they return a value. The default return value from
|
||||
include() and eval() is 1, so that you can do if (include())
|
||||
without further coding. The return value may be changed by
|
||||
returning a value from the global scope of the included file
|
||||
or the evaluated string. For example, if 'return 7;' is executed
|
||||
in the global scope of foo.inc, include("foo.inc") would evaluate
|
||||
to 7.
|
||||
* Automatic resource deallocation. Several people have been bitten
|
||||
by the fact that PHP 3.0 had no concept of reference counting.
|
||||
Zend adds full reference counting for every value in the system,
|
||||
including resources. As soon as a resource is no longer referenced
|
||||
from any variable, it is automatically destroyed to save memory
|
||||
and resources. The most obvious example for the advantage in this
|
||||
is a loop that has an SQL query inside it, something like
|
||||
'$result = sql_query(...);'. In PHP 3.0, every iteration resulted
|
||||
in another SQL result-set allocated in the memory, and all of the
|
||||
result sets weren't destroyed until the end of the script's execution.
|
||||
In Zend, as soon as we overwrite an old result set with a new one,
|
||||
the old result set which is no longer referenced, is destroyed.
|
||||
* Full support for nesting arrays and objects within each other, in
|
||||
as many levels as you want.
|
||||
* Boolean type. true and false are now constants of type boolean.
|
||||
Comparing any other value to them would convert that value to a
|
||||
boolean first, and conduct the comparison later. That means, for
|
||||
example, that 5==true would evaluate to true (in PHP 3.0, true
|
||||
was nothing but a constant for the integer value of 1, so 5==true
|
||||
was identical to 5==1, which was false).
|
||||
* Runtime binding of function names. This complex name has a simple
|
||||
explanation - you can now call functions before they're declared!
|
||||
* Added here-docs support.
|
||||
* Added foreach. Two syntaxes supported:
|
||||
foreach($val in array_expr) statement
|
||||
foreach($key, $val in array_expr) statement
|
||||
* A true unset() implementation. A variable or element that is unset(), is now
|
||||
sent to oblivion in its entirely, no trace remains from it.
|
||||
* Output buffering support! Use ob_start() to begin output buffering, ob_end_flush()
|
||||
to end buffering and send out the buffered contents, ob_end_clean() to end buffering
|
||||
without sending the buffered contents, and ob_get_contents() to retreive the current
|
||||
contents of the output buffer.
|
||||
Header information (header(), content type, cookies) are not buffered. By turning
|
||||
on output buffering, you can effectively send header information all throughout your
|
||||
file, regardless of whether you've emitted body output or not.
|
||||
* Full variable reference within quoted strings:
|
||||
${expr} - full indirect reference support for scalar variables
|
||||
{variable} - full variable support
|
||||
For example:
|
||||
$foo[5]["bar"] = "foobar";
|
||||
print "{$foo[5]["bar"]}"; // would print "foobar"
|
||||
* Ability to call member functions of other classes from within member functions or from
|
||||
the global scope. You can now, for example, override a parent function with a child function,
|
||||
and call the parent function from it.
|
||||
* Runtime information for classes (class name, parent, available functions, etc.).
|
||||
* Much more efficient syntax highlighter - runs much quicker, performs more reliably, and
|
||||
generates much tighter HTML.
|
||||
* A full-featured debugger has been integrated with the language (supports breakpoints,
|
||||
expression evaluation, step-in/over, function call backtrace, and more).
|
||||
|
||||
|
||||
Incompatabilities
|
||||
-----------------
|
||||
|
||||
Zend claims 100% compatability with the engine of PHP 3.0, and is
|
||||
shamelessly lying about it. Here's why:
|
||||
|
||||
* static variable initializers only accept scalar values
|
||||
(in PHP 3.0 they accepted any valid expression). The impact
|
||||
should be somewhere in between void and non existant, since
|
||||
initializing a static variable with anything but a simple
|
||||
static value makes no sense at all.
|
||||
|
||||
* The scope of break and continue is local to that of an
|
||||
include()'d file or an eval()'d string. The impact should
|
||||
be somewhat smaller of the one above.
|
||||
|
||||
* return statement from a require()'d file no longer works. It
|
||||
hardly worked in PHP 3.0, so the impact should be fairly small.
|
||||
If you want this functionality - use include() instead.
|
||||
|
||||
* unset() is no longer a function, but a statement. It was never
|
||||
documented as a function so the impact should be no bigger than
|
||||
nada.
|
||||
|
||||
* The following letter combination is not supported within encapsulated
|
||||
strings: "{$". If you have a string that includes this letter
|
||||
combination, for example, print "{$somevar"; (which printed the
|
||||
letter { and the contents of the variable $somevar in PHP 3.0),
|
||||
it will result in a parse error under Zend. In this case, you
|
||||
would have to change the code to print "\{$somevar";
|
||||
This incompatability is due to the full variable reference
|
||||
within quoted strings feature added in Zend.
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
# Microsoft Developer Studio Generated Dependency File, included by ZendCore.mak
|
||||
|
||||
.\zend_alloc.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\alloca.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_compile.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_API.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
|
||||
|
||||
.\zend_constants.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_constants.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_execute.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_API.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
|
||||
|
||||
.\zend_highlight.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_highlight.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend-parser.tab.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_llist.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_opcode.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_API.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
|
||||
|
||||
.\zend_operators.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_ptr_stack.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_stack.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_variables.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\modules.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_API.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
".\zend_list.h"\
|
||||
|
||||
|
||||
.\zend.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_API.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\zend_compile.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend_constants.h"\
|
||||
".\zend_execute.h"\
|
||||
".\zend_llist.h"\
|
||||
".\modules.h"\
|
||||
".\zend_operators.h"\
|
||||
".\zend_ptr_stack.h"\
|
||||
".\zend_stack.h"\
|
||||
".\zend_variables.h"\
|
||||
".\zend.h"\
|
||||
".\zend_API.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_globals.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
".\zend_list.h"\
|
||||
|
||||
|
||||
.\zend_hash.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
|
||||
|
||||
.\zend_ini.c : \
|
||||
"..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
|
||||
".\zend_alloc.h"\
|
||||
".\config.w32.h"\
|
||||
".\zend.h"\
|
||||
".\zend_errors.h"\
|
||||
".\zend_hash.h"\
|
||||
".\zend_ini.h"\
|
||||
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
# Microsoft Developer Studio Project File - Name="ZendCore" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=ZendCore - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZendCore.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZendCore.mak" CFG="ZendCore - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ZendCore - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZendCore - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "COMPILE_LIBZEND" /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)" == "ZendCore - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "COMPILE_LIBZEND" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x40d /d "_DEBUG"
|
||||
# ADD RSC /l 0x40d /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ZendCore - Win32 Release"
|
||||
# Name "ZendCore - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\alloca.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sprintf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-parser.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-scanner.c"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_alloc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_API.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_compile.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_constants.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute_API.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_extensions.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_highlight.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_indent.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_llist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_opcode.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_operators.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ptr_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\config.w32.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\modules.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-parser.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-scanner.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_alloc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_API.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_compile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_constants.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_errors.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_execute.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_extensions.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_globals.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_hash.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_highlight.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_indent.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_list.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_llist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_operators.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_ptr_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_stack.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend_variables.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Parsers"
|
||||
|
||||
# PROP Default_Filter "y"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-parser.y"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y
|
||||
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputDir=.
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
BuildCmds= \
|
||||
bison --output=zend-parser.c -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y
|
||||
|
||||
"$(InputDir)\zend-parser.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
|
||||
"$(InputDir)\zend-parser.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
$(BuildCmds)
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Scanners"
|
||||
|
||||
# PROP Default_Filter "l"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=".\zend-scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
"zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
flex -i -Pzend -ozend-scanner.c zend-scanner.l
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Text Files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZEND_BUGS
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZEND_CHANGES
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZEND_TODO
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resources"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zend.ico
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,65 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ZendCore"=.\ZendCore.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ZendDebugger"=..\ZendDebugger\ZendDebugger.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ZendOpArrayViewer"=..\ZendOpArrayViewer\ZendOpArrayViewer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ZendOptimizer"=..\ZendOptimizer\ZendOptimizer.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,628 @@
|
||||
# Microsoft Developer Studio Generated NMAKE File, Based on ZendCore.dsp
|
||||
!IF "$(CFG)" == ""
|
||||
CFG=ZendCore - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to ZendCore - Win32 Debug.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "ZendCore - Win32 Release" && "$(CFG)" != "ZendCore - Win32 Debug"
|
||||
!MESSAGE Invalid configuration "$(CFG)" specified.
|
||||
!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 "ZendCore.mak" CFG="ZendCore - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ZendCore - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZendCore - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified.
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT"
|
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\ZendCore.lib"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\alloc.obj"
|
||||
-@erase "$(INTDIR)\alloca.obj"
|
||||
-@erase "$(INTDIR)\compile.obj"
|
||||
-@erase "$(INTDIR)\constants.obj"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\highlight.obj"
|
||||
-@erase "$(INTDIR)\llist.obj"
|
||||
-@erase "$(INTDIR)\opcode.obj"
|
||||
-@erase "$(INTDIR)\operators.obj"
|
||||
-@erase "$(INTDIR)\ptr_stack.obj"
|
||||
-@erase "$(INTDIR)\sprintf.obj"
|
||||
-@erase "$(INTDIR)\stack.obj"
|
||||
-@erase "$(INTDIR)\variables.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\zend.obj"
|
||||
-@erase "$(INTDIR)\zend_API.obj"
|
||||
-@erase "$(INTDIR)\zend_hash.obj"
|
||||
-@erase "$(INTDIR)\zend_ini.obj"
|
||||
-@erase "$(OUTDIR)\ZendCore.lib"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR)\ZendCore.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
RSC=rc.exe
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\ZendCore.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LIB32=link.exe -lib
|
||||
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ZendCore.lib"
|
||||
LIB32_OBJS= \
|
||||
"$(INTDIR)\alloc.obj" \
|
||||
"$(INTDIR)\alloca.obj" \
|
||||
"$(INTDIR)\compile.obj" \
|
||||
"$(INTDIR)\constants.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\highlight.obj" \
|
||||
"$(INTDIR)\llist.obj" \
|
||||
"$(INTDIR)\opcode.obj" \
|
||||
"$(INTDIR)\operators.obj" \
|
||||
"$(INTDIR)\ptr_stack.obj" \
|
||||
"$(INTDIR)\sprintf.obj" \
|
||||
"$(INTDIR)\stack.obj" \
|
||||
"$(INTDIR)\variables.obj" \
|
||||
"$(INTDIR)\zend.obj" \
|
||||
"$(INTDIR)\zend_hash.obj" \
|
||||
"$(INTDIR)\zend_ini.obj" \
|
||||
"$(INTDIR)\zend_API.obj"
|
||||
|
||||
"$(OUTDIR)\ZendCore.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
|
||||
$(LIB32) @<<
|
||||
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
|
||||
<<
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
ALL : ".\zend-scanner.c" ".\zend-parser.tab.h" ".\zend-parser.tab.c" ".\configuration-scanner.c" ".\configuration-parser.tab.h" ".\configuration-parser.tab.c" "$(OUTDIR)\ZendCore.lib" "$(OUTDIR)\ZendCore.bsc"
|
||||
|
||||
|
||||
CLEAN :
|
||||
-@erase "$(INTDIR)\alloc.obj"
|
||||
-@erase "$(INTDIR)\alloc.sbr"
|
||||
-@erase "$(INTDIR)\alloca.obj"
|
||||
-@erase "$(INTDIR)\alloca.sbr"
|
||||
-@erase "$(INTDIR)\compile.obj"
|
||||
-@erase "$(INTDIR)\compile.sbr"
|
||||
-@erase "$(INTDIR)\constants.obj"
|
||||
-@erase "$(INTDIR)\constants.sbr"
|
||||
-@erase "$(INTDIR)\execute.obj"
|
||||
-@erase "$(INTDIR)\execute.sbr"
|
||||
-@erase "$(INTDIR)\highlight.obj"
|
||||
-@erase "$(INTDIR)\highlight.sbr"
|
||||
-@erase "$(INTDIR)\llist.obj"
|
||||
-@erase "$(INTDIR)\llist.sbr"
|
||||
-@erase "$(INTDIR)\opcode.obj"
|
||||
-@erase "$(INTDIR)\opcode.sbr"
|
||||
-@erase "$(INTDIR)\operators.obj"
|
||||
-@erase "$(INTDIR)\operators.sbr"
|
||||
-@erase "$(INTDIR)\ptr_stack.obj"
|
||||
-@erase "$(INTDIR)\ptr_stack.sbr"
|
||||
-@erase "$(INTDIR)\sprintf.obj"
|
||||
-@erase "$(INTDIR)\sprintf.sbr"
|
||||
-@erase "$(INTDIR)\stack.obj"
|
||||
-@erase "$(INTDIR)\stack.sbr"
|
||||
-@erase "$(INTDIR)\variables.obj"
|
||||
-@erase "$(INTDIR)\variables.sbr"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(INTDIR)\zend.obj"
|
||||
-@erase "$(INTDIR)\zend.sbr"
|
||||
-@erase "$(INTDIR)\zend_API.obj"
|
||||
-@erase "$(INTDIR)\zend_API.sbr"
|
||||
-@erase "$(INTDIR)\zend_hash.obj"
|
||||
-@erase "$(INTDIR)\zend_hash.sbr"
|
||||
-@erase "$(INTDIR)\zend_ini.obj"
|
||||
-@erase "$(INTDIR)\zend_ini.sbr"
|
||||
-@erase "$(OUTDIR)\ZendCore.bsc"
|
||||
-@erase "$(OUTDIR)\ZendCore.lib"
|
||||
-@erase "configuration-parser.tab.c"
|
||||
-@erase "configuration-parser.tab.h"
|
||||
-@erase "configuration-scanner.c"
|
||||
-@erase "zend-parser.tab.c"
|
||||
-@erase "zend-parser.tab.h"
|
||||
-@erase "zend-scanner.c"
|
||||
|
||||
"$(OUTDIR)" :
|
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP=cl.exe
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\ZendCore.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
|
||||
.c{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.c{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx{$(INTDIR)}.sbr::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
RSC=rc.exe
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\ZendCore.bsc"
|
||||
BSC32_SBRS= \
|
||||
"$(INTDIR)\alloc.sbr" \
|
||||
"$(INTDIR)\alloca.sbr" \
|
||||
"$(INTDIR)\compile.sbr" \
|
||||
"$(INTDIR)\constants.sbr" \
|
||||
"$(INTDIR)\execute.sbr" \
|
||||
"$(INTDIR)\highlight.sbr" \
|
||||
"$(INTDIR)\llist.sbr" \
|
||||
"$(INTDIR)\opcode.sbr" \
|
||||
"$(INTDIR)\operators.sbr" \
|
||||
"$(INTDIR)\ptr_stack.sbr" \
|
||||
"$(INTDIR)\sprintf.sbr" \
|
||||
"$(INTDIR)\stack.sbr" \
|
||||
"$(INTDIR)\variables.sbr" \
|
||||
"$(INTDIR)\zend.sbr" \
|
||||
"$(INTDIR)\zend_hash.sbr" \
|
||||
"$(INTDIR)\zend_ini.sbr" \
|
||||
"$(INTDIR)\zend_API.sbr"
|
||||
|
||||
"$(OUTDIR)\ZendCore.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
|
||||
$(BSC32) @<<
|
||||
$(BSC32_FLAGS) $(BSC32_SBRS)
|
||||
<<
|
||||
|
||||
LIB32=link.exe -lib
|
||||
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ZendCore.lib"
|
||||
LIB32_OBJS= \
|
||||
"$(INTDIR)\alloc.obj" \
|
||||
"$(INTDIR)\alloca.obj" \
|
||||
"$(INTDIR)\compile.obj" \
|
||||
"$(INTDIR)\constants.obj" \
|
||||
"$(INTDIR)\execute.obj" \
|
||||
"$(INTDIR)\highlight.obj" \
|
||||
"$(INTDIR)\llist.obj" \
|
||||
"$(INTDIR)\opcode.obj" \
|
||||
"$(INTDIR)\operators.obj" \
|
||||
"$(INTDIR)\ptr_stack.obj" \
|
||||
"$(INTDIR)\sprintf.obj" \
|
||||
"$(INTDIR)\stack.obj" \
|
||||
"$(INTDIR)\variables.obj" \
|
||||
"$(INTDIR)\zend.obj" \
|
||||
"$(INTDIR)\zend_hash.obj" \
|
||||
"$(INTDIR)\zend_ini.obj" \
|
||||
"$(INTDIR)\zend_API.obj"
|
||||
|
||||
"$(OUTDIR)\ZendCore.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
|
||||
$(LIB32) @<<
|
||||
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
|
||||
<<
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1"
|
||||
!IF EXISTS("ZendCore.dep")
|
||||
!INCLUDE "ZendCore.dep"
|
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "ZendCore.dep"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release" || "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
SOURCE=.\zend_alloc.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\alloc.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\alloc.obj" "$(INTDIR)\alloc.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\alloca.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\alloca.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\alloca.obj" "$(INTDIR)\alloca.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_compile.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\compile.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\compile.obj" "$(INTDIR)\compile.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_constants.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\constants.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\constants.obj" "$(INTDIR)\constants.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_execute.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\execute.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\execute.obj" "$(INTDIR)\execute.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_highlight.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\highlight.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\highlight.obj" "$(INTDIR)\highlight.sbr" : $(SOURCE) "$(INTDIR)" ".\zend-parser.tab.h"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_llist.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\llist.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\llist.obj" "$(INTDIR)\llist.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_opcode.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\opcode.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\opcode.obj" "$(INTDIR)\opcode.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_operators.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\operators.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\operators.obj" "$(INTDIR)\operators.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_ptr_stack.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\ptr_stack.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\ptr_stack.obj" "$(INTDIR)\ptr_stack.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\sprintf.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\sprintf.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\sprintf.obj" "$(INTDIR)\sprintf.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_stack.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\stack.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\stack.obj" "$(INTDIR)\stack.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_variables.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\variables.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\variables.obj" "$(INTDIR)\variables.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\zend.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\zend.obj" "$(INTDIR)\zend.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_API.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_API.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_API.obj" "$(INTDIR)\zend_API.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_hash.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_hash.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_hash.obj" "$(INTDIR)\zend_hash.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=.\zend_ini.c
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_ini.obj" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
|
||||
"$(INTDIR)\zend_ini.obj" "$(INTDIR)\zend_ini.sbr" : $(SOURCE) "$(INTDIR)"
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=".\configuration-parser.y"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
InputPath=".\configuration-parser.y"
|
||||
|
||||
".\configuration-parser.tab.c" ".\configuration-parser.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
bison -d -S "C:\Program Files\Cygnus\share\bison.simple" -p cfg configuration-parser.y
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=".\zend-parser.y"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
InputPath=".\zend-parser.y"
|
||||
|
||||
".\zend-parser.tab.c" ".\zend-parser.tab.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
bison -v -d -S "C:\Program Files\Cygnus\share\bison.simple" -p zend zend-parser.y
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=".\configuration-scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
InputPath=".\configuration-scanner.l"
|
||||
|
||||
".\configuration-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
flex -i -Pcfg -oconfiguration-scanner.c configuration-scanner.l
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
SOURCE=".\zend-scanner.l"
|
||||
|
||||
!IF "$(CFG)" == "ZendCore - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZendCore - Win32 Debug"
|
||||
|
||||
InputPath=".\zend-scanner.l"
|
||||
|
||||
".\zend-scanner.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
<<tempfile.bat
|
||||
@echo off
|
||||
flex -i -Pzend -ozend-scanner.c zend-scanner.l
|
||||
<<
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
/* This is the default configuration file to read */
|
||||
#define USE_CONFIG_FILE 1
|
||||
|
||||
/* define uint by configure if it is missed (QNX and BSD derived) */
|
||||
#undef uint
|
||||
|
||||
/* define ulong by configure if it is missed (most probably is) */
|
||||
#undef ulong
|
||||
|
||||
/* type check for in_addr_t */
|
||||
#undef in_addr_t
|
||||
|
||||
/* Solaris YP check */
|
||||
#undef SOLARIS_YP
|
||||
|
||||
/* Netscape LDAP SDK check */
|
||||
#undef HAVE_NSLDAP
|
||||
|
||||
/* ImageMagick check */
|
||||
#undef HAVE_LIBMAGICK
|
||||
|
||||
/* Define if you have dirent.h but opendir() resides in libc rather than in libdir */
|
||||
/* This will cause HAVE_DIRENT_H defined twice sometimes, but it should be problem */
|
||||
#define HAVE_DIRENT_H 0
|
||||
|
||||
/* Define if you have struct flock */
|
||||
#define HAVE_STRUCT_FLOCK 0
|
||||
|
||||
/* Define if you have the resolv library (-lresolv). */
|
||||
#define HAVE_LIBRESOLV 0
|
||||
|
||||
/* Define if you have the gd library (-lgd). */
|
||||
#define HAVE_LIBGD 0
|
||||
|
||||
/* Define if you have the GNU gettext library (-lintl). */
|
||||
#define HAVE_LIBINTL 0
|
||||
|
||||
/* Define if you have the zlib library */
|
||||
#define HAVE_ZLIB 0
|
||||
|
||||
/* Define if you have the gd version 1.3 library (-lgd). */
|
||||
#define HAVE_LIBGD13 0
|
||||
|
||||
/* Undefine if you want stricter XML/SGML compliance by default */
|
||||
/* (this disables "<?expression?>" by default) */
|
||||
#define DEFAULT_SHORT_OPEN_TAG 1
|
||||
|
||||
/* Define if you want the logging to go to ndbm/gdbm/flatfile */
|
||||
#define LOG_DBM 0
|
||||
#define LOG_DBM_DIR "."
|
||||
|
||||
/* Define if you want the logging to go to a mysql database */
|
||||
#define LOG_MYSQL 0
|
||||
|
||||
/* Define if you want the logging to go to a mysql database */
|
||||
#define LOG_MSQL 0
|
||||
|
||||
/* Define these if you are using an SQL database for logging */
|
||||
#define LOG_SQL_HOST ""
|
||||
#define LOG_SQL_DB ""
|
||||
|
||||
/* Define if you an ndbm compatible library (-ldbm). */
|
||||
#define NDBM 0
|
||||
|
||||
/* Define if you have the gdbm library (-lgdbm). */
|
||||
#define GDBM 0
|
||||
|
||||
/* Define both of these if you want the bundled REGEX library */
|
||||
#define REGEX 0
|
||||
#define HSREGEX 0
|
||||
|
||||
/* Define if you want Solid database support */
|
||||
#define HAVE_SOLID 0
|
||||
|
||||
/* Define if you want to use the supplied dbase library */
|
||||
#define DBASE 0
|
||||
|
||||
/* Define if you want Hyperwave support */
|
||||
#define HYPERWAVE 0
|
||||
|
||||
/* Define if you have the crypt() function */
|
||||
#define HAVE_CRYPT 1
|
||||
|
||||
/* Define if you have the Oracle database client libraries */
|
||||
#define HAVE_ORACLE 0
|
||||
|
||||
/* Define if you have the Oracle version 8 database client libraries */
|
||||
#define HAVE_OCI8 0
|
||||
|
||||
/* Define if you want to use the iODBC database driver */
|
||||
#define HAVE_IODBC 0
|
||||
|
||||
/* Define if you want to use the OpenLink ODBC database driver */
|
||||
#define HAVE_OPENLINK 0
|
||||
|
||||
/* Define if you have the AdabasD client libraries */
|
||||
#define HAVE_ADABAS 0
|
||||
|
||||
/* Define if you want the LDAP directory interface */
|
||||
#define HAVE_LDAP 0
|
||||
|
||||
/* Define if you want the Cybercash MCK support */
|
||||
#define HAVE_MCK 0
|
||||
|
||||
/* Define if you want the SNMP interface */
|
||||
#define HAVE_SNMP 0
|
||||
|
||||
/* Define if you want the IMAP directory interface */
|
||||
#define HAVE_IMAP 0
|
||||
|
||||
/* Define if you want the ASPELL interface */
|
||||
#define HAVE_ASPELL 0
|
||||
|
||||
/* Define if you want to use a custom ODBC database driver */
|
||||
#define HAVE_CODBC 0
|
||||
|
||||
/* Define to use the unified ODBC interface */
|
||||
#define HAVE_UODBC 0
|
||||
|
||||
/* Define if you have libdl (used for dynamic linking) */
|
||||
#define HAVE_LIBDL 0
|
||||
|
||||
/* Define if you have libdnet_stub (used for Sybase support) */
|
||||
#define HAVE_LIBDNET_STUB 0
|
||||
|
||||
/* Define if you have and want to use libcrypt */
|
||||
#define HAVE_LIBCRYPT 0
|
||||
|
||||
/* Define if you have and want to use libnsl */
|
||||
#define HAVE_LIBNSL 0
|
||||
|
||||
/* Define if you have and want to use libsocket */
|
||||
#define HAVE_LIBSOCKET 0
|
||||
|
||||
/* Define if you have and want to use libpam */
|
||||
#define HAVE_LIBPAM 0
|
||||
|
||||
/* Define if you have the sendmail program available */
|
||||
#define HAVE_SENDMAIL 0
|
||||
|
||||
/* Define if your Apache creates an ap_config.h header file (only 1.3b6 and later) */
|
||||
#define HAVE_AP_CONFIG_H 0
|
||||
|
||||
/* Define if your Apache has src/include/compat.h */
|
||||
#define HAVE_OLD_COMPAT_H 0
|
||||
|
||||
/* Define if your Apache has src/include/ap_compat.h */
|
||||
#define HAVE_AP_COMPAT_H 0
|
||||
|
||||
#ifndef HAVE_EMPRESS
|
||||
#define HAVE_EMPRESS 0
|
||||
#endif
|
||||
|
||||
#define HAVE_SYBASE 0
|
||||
#define HAVE_SYBASE_CT 0
|
||||
|
||||
#ifndef HAVE_MYSQL
|
||||
#define HAVE_MYSQL 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MSQL
|
||||
#define HAVE_MSQL 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PGSQL
|
||||
#define HAVE_PGSQL 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_VELOCIS
|
||||
#define HAVE_VELOCIS 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_IFX
|
||||
#define HAVE_IFX 0
|
||||
#endif
|
||||
#ifndef HAVE_IFX_IUS
|
||||
#define HAVE_IFX_IUS 0
|
||||
#endif
|
||||
#ifndef IFX_VERSION
|
||||
#define IFX_VERSION 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_IBASE
|
||||
#define HAVE_IBASE 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PQCMDTUPLES
|
||||
#define HAVE_PQCMDTUPLES 0
|
||||
#endif
|
||||
|
||||
#undef ZEND_DEBUG
|
||||
|
||||
/* Define if your system has the gettimeofday() call */
|
||||
#define HAVE_GETTIMEOFDAY 0
|
||||
|
||||
/* Define if your system has the getrusage() call */
|
||||
#define HAVE_GETRUSAGE 0
|
||||
|
||||
/* Define if your system has the putenv() library call */
|
||||
#define HAVE_PUTENV 0
|
||||
|
||||
/* Define if you want to enable bc style precision math support */
|
||||
#define WITH_BCMATH 0
|
||||
|
||||
/* Define if you want to prevent the CGI from working unless REDIRECT_STATUS is defined in the environment */
|
||||
#define FORCE_CGI_REDIRECT 0
|
||||
|
||||
/* Define if you want to prevent the CGI from using path_info and path_translated */
|
||||
#define DISCARD_PATH 0
|
||||
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
|
||||
/* Define if you want System V semaphore support.
|
||||
*/
|
||||
#define HAVE_SYSVSEM 0
|
||||
|
||||
/* Define if you have union semun.
|
||||
*/
|
||||
#define HAVE_SEMUN 0
|
||||
|
||||
/* Define if you want System V shared memory support. */
|
||||
#define HAVE_SYSVSHM 0
|
||||
|
||||
/* Define if you want to enable displaying source support. */
|
||||
#define HAVE_DISPLAY_SOURCE 0
|
||||
|
||||
/* Define if you have broken header files like SunOS 4 */
|
||||
#define MISSING_FCLOSE_DECL 0
|
||||
|
||||
/* Define if you have broken sprintf function like SunOS 4 */
|
||||
#define BROKEN_SPRINTF 0
|
||||
|
||||
/* Define if you have the expat (XML Parser Toolkit) library */
|
||||
#define HAVE_LIBEXPAT 0
|
||||
|
||||
/* Define if you have the pdflib library */
|
||||
#define HAVE_PDFLIB 0
|
||||
|
||||
/* Define if you have the fdftk library */
|
||||
#define HAVE_FDFLIB 0
|
||||
|
||||
/* Define to compile with mod_dav support */
|
||||
#define HAVE_MOD_DAV 0
|
||||
|
||||
/* Define to enable yp/nis support */
|
||||
#define HAVE_YP 0
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
dnl $Id$
|
||||
dnl
|
||||
dnl This file contains local autoconf functions.
|
||||
|
||||
dnl
|
||||
dnl Check for broken sprintf()
|
||||
dnl
|
||||
AC_DEFUN(AC_BROKEN_SPRINTF,[
|
||||
AC_MSG_CHECKING([for broken sprintf])
|
||||
AC_TRY_RUN([main() { char buf[20]; exit (sprintf(buf,"testing 123")!=11); }],[
|
||||
AC_DEFINE(BROKEN_SPRINTF,0)
|
||||
AC_MSG_RESULT(ok)
|
||||
],[
|
||||
AC_DEFINE(BROKEN_SPRINTF,1)
|
||||
AC_MSG_RESULT(broken)
|
||||
],[
|
||||
AC_DEFINE(BROKEN_SPRINTF,0)
|
||||
AC_MSG_RESULT(cannot check, guessing ok)
|
||||
])
|
||||
])
|
||||
# another one stolen from automake temporarily
|
||||
#
|
||||
# Check to make sure that the build environment is sane.
|
||||
#
|
||||
|
||||
AC_DEFUN(AM_SANITY_CHECK,
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftestfile
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
|
||||
if test "$@" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t $srcdir/configure conftestfile`
|
||||
fi
|
||||
test "[$]2" = conftestfile
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
rm -f conftest*
|
||||
AC_MSG_RESULT(yes)])
|
||||
@@ -0,0 +1,274 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* define uint by configure if it is missed (QNX and BSD derived) */
|
||||
#undef uint
|
||||
|
||||
/* define ulong by configure if it is missed (most probably is) */
|
||||
#undef ulong
|
||||
|
||||
/* Define if you have the resolv library (-lresolv). */
|
||||
#define HAVE_LIBRESOLV 0
|
||||
|
||||
/* Define if you have libdl (used for dynamic linking) */
|
||||
#define HAVE_LIBDL 0
|
||||
|
||||
/* Define if you have and want to use libnsl */
|
||||
#define HAVE_LIBNSL 0
|
||||
|
||||
/* Define if you have and want to use libsocket */
|
||||
#define HAVE_LIBSOCKET 0
|
||||
|
||||
#undef ZEND_DEBUG
|
||||
|
||||
/* Define if you want to enable memory limit support */
|
||||
#define MEMORY_LIMIT 0
|
||||
|
||||
/* Define if you have broken sprintf function like SunOS 4 */
|
||||
#define BROKEN_SPRINTF 0
|
||||
|
||||
/* Define if you have the crypt function. */
|
||||
#undef HAVE_CRYPT
|
||||
|
||||
/* Define if you have the cuserid function. */
|
||||
#undef HAVE_CUSERID
|
||||
|
||||
/* Define if you have the flock function. */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
/* Define if you have the gcvt function. */
|
||||
#undef HAVE_GCVT
|
||||
|
||||
/* Define if you have the getlogin function. */
|
||||
#undef HAVE_GETLOGIN
|
||||
|
||||
/* Define if you have the getopt function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the inet_aton function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
/* Define if you have the link function. */
|
||||
#undef HAVE_LINK
|
||||
|
||||
/* Define if you have the lockf function. */
|
||||
#undef HAVE_LOCKF
|
||||
|
||||
/* Define if you have the lrand48 function. */
|
||||
#undef HAVE_LRAND48
|
||||
|
||||
/* Define if you have the memcpy function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define if you have the memmove function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define if you have the putenv function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define if you have the random function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define if you have the regcomp function. */
|
||||
#undef HAVE_REGCOMP
|
||||
|
||||
/* Define if you have the rint function. */
|
||||
#undef HAVE_RINT
|
||||
|
||||
/* Define if you have the setitimer function. */
|
||||
#undef HAVE_SETITIMER
|
||||
|
||||
/* Define if you have the setlocale function. */
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* Define if you have the setsockopt function. */
|
||||
#undef HAVE_SETSOCKOPT
|
||||
|
||||
/* Define if you have the setvbuf function. */
|
||||
#undef HAVE_SETVBUF
|
||||
|
||||
/* Define if you have the snprintf function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define if you have the srand48 function. */
|
||||
#undef HAVE_SRAND48
|
||||
|
||||
/* Define if you have the srandom function. */
|
||||
#undef HAVE_SRANDOM
|
||||
|
||||
/* Define if you have the statfs function. */
|
||||
#undef HAVE_STATFS
|
||||
|
||||
/* Define if you have the statvfs function. */
|
||||
#undef HAVE_STATVFS
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
/* Define if you have the symlink function. */
|
||||
#undef HAVE_SYMLINK
|
||||
|
||||
/* Define if you have the tempnam function. */
|
||||
#undef HAVE_TEMPNAM
|
||||
|
||||
/* Define if you have the tzset function. */
|
||||
#undef HAVE_TZSET
|
||||
|
||||
/* Define if you have the unsetenv function. */
|
||||
#undef HAVE_UNSETENV
|
||||
|
||||
/* Define if you have the usleep function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define if you have the utime function. */
|
||||
#undef HAVE_UTIME
|
||||
|
||||
/* Define if you have the vsnprintf function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define if you have the <crypt.h> header file. */
|
||||
#undef HAVE_CRYPT_H
|
||||
|
||||
/* Define if you have the <db.h> header file. */
|
||||
#undef HAVE_DB_H
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define if you have the <ndbm.h> header file. */
|
||||
#undef HAVE_NDBM_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#undef HAVE_SIGNAL_H
|
||||
|
||||
/* Define if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define if you have the <sys/statfs.h> header file. */
|
||||
#undef HAVE_SYS_STATFS_H
|
||||
|
||||
/* Define if you have the <sys/statvfs.h> header file. */
|
||||
#undef HAVE_SYS_STATVFS_H
|
||||
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define if you have the <sys/varargs.h> header file. */
|
||||
#undef HAVE_SYS_VARARGS_H
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the <unix.h> header file. */
|
||||
#undef HAVE_UNIX_H
|
||||
|
||||
/* Define if you have the m library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define if you have the resolv library (-lresolv). */
|
||||
#undef HAVE_LIBRESOLV
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef _CONFIG_UNIX_H
|
||||
#define _CONFIG_UNIX_H
|
||||
|
||||
#define ZEND_API
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBDL
|
||||
# include <dlfcn.h>
|
||||
# define DL_LOAD(libname) dlopen(libname, RTLD_NOW)
|
||||
# define DL_UNLOAD dlclose
|
||||
# define DL_FETCH_SYMBOL dlsym
|
||||
# define DL_HANDLE void *
|
||||
# define ZEND_EXTENSIONS_SUPPORT 1
|
||||
#else
|
||||
# define ZEND_EXTENSIONS_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#if BROKEN_SPRINTF
|
||||
int zend_sprintf(char *buffer, const char *format, ...);
|
||||
#else
|
||||
# define zend_sprintf sprintf
|
||||
#endif
|
||||
|
||||
#if ZEND_DEBUG
|
||||
# define inline
|
||||
#endif
|
||||
|
||||
#endif /* _CONFIG_UNIX_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef _ZEND_CONFIG_W32_H
|
||||
#define _ZEND_CONFIG_W32_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define HAVE_ALLOCA 1
|
||||
#include <malloc.h>
|
||||
|
||||
#define HAVE_DIRENT_H 0
|
||||
|
||||
#ifdef inline
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
#define ZEND_DEBUG 1
|
||||
|
||||
#define zend_sprintf sprintf
|
||||
|
||||
/* Visual C++ doesn't really work with inline for C */
|
||||
#define inline
|
||||
|
||||
|
||||
#define DL_LOAD(libname) LoadLibrary(libname)
|
||||
#define DL_FETCH_SYMBOL GetProcAddress
|
||||
#define DL_UNLOAD FreeLibrary
|
||||
#define DL_HANDLE HMODULE
|
||||
#define ZEND_EXTENSIONS_SUPPORT 1
|
||||
|
||||
#ifdef COMPILE_LIBZEND
|
||||
# define ZEND_API __declspec(dllexport)
|
||||
#else
|
||||
# define ZEND_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ZEND_CONFIG_W32_H */
|
||||
@@ -0,0 +1,194 @@
|
||||
dnl $Id$
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(zend.c)
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AM_SANITY_CHECK
|
||||
|
||||
dnl We want this one before the checks, so the checks can modify CFLAGS.
|
||||
test -z "$CFLAGS" && auto_cflags=1
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_YACC
|
||||
if test "$YACC" != "bison -y"; then
|
||||
AC_MSG_WARN(You will need bison if you'd want to regenerate the PHP 3.0 parsers.)
|
||||
else
|
||||
AC_MSG_CHECKING(bison version)
|
||||
set `bison --version| sed -e 's/^GNU Bison version //' -e 's/\./ /'`
|
||||
if test "$1" = "1" -a "$2" -lt "25"; then
|
||||
AC_MSG_WARN(You will need bison 1.25 if you'd want to regenerate the PHP 3.0 parsers (found $1.$2).)
|
||||
fi
|
||||
AC_MSG_RESULT($1.$2 (ok))
|
||||
fi
|
||||
AC_PROG_CC
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_CC_C_O
|
||||
AC_PATH_PROG(PERL_PATH, perl)
|
||||
|
||||
dnl Ugly hack to get around a problem with gcc on AIX.
|
||||
if test "$CC" = "gcc" -a "$ac_cv_prog_cc_g" = "yes" -a \
|
||||
"`uname -sv`" = "AIX 4"; then
|
||||
CFLAGS=`echo $CFLAGS | sed -e 's/-g//'`
|
||||
fi
|
||||
|
||||
dnl check for -R, etc. switch
|
||||
AC_MSG_CHECKING(if compiler supports -R)
|
||||
AC_CACHE_VAL(php_cv_cc_dashr,[
|
||||
SAVE_LIBS="${LIBS}"
|
||||
LIBS="-R /usr/lib ${LIBS}"
|
||||
AC_TRY_LINK([], [], php_cv_cc_dashr=yes, php_cv_cc_dashr=no)
|
||||
LIBS="${SAVE_LIBS}"])
|
||||
AC_MSG_RESULT($php_cv_cc_dashr)
|
||||
if test $php_cv_cc_dashr = "yes"; then
|
||||
ld_runpath_switch="-R"
|
||||
apxs_runpath_switch="-Wl,-R'"
|
||||
else
|
||||
AC_MSG_CHECKING([if compiler supports -Wl,-rpath,])
|
||||
AC_CACHE_VAL(php_cv_cc_rpath,[
|
||||
SAVE_LIBS="${LIBS}"
|
||||
LIBS="-Wl,-rpath,/usr/lib ${LIBS}"
|
||||
AC_TRY_LINK([], [], php_cv_cc_rpath=yes, php_cv_cc_rpath=no)
|
||||
LIBS="${SAVE_LIBS}"])
|
||||
AC_MSG_RESULT($php_cv_cc_rpath)
|
||||
if test $php_cv_cc_rpath = "yes"; then
|
||||
ld_runpath_switch="-Wl,-rpath,"
|
||||
apxs_runpath_switch="-Wl,'-rpath "
|
||||
else
|
||||
dnl something innocuous
|
||||
ld_runpath_switch="-L"
|
||||
apxs_runpath_switch="-L'"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check for /usr/pkg/{lib,include} which is where NetBSD puts binary
|
||||
dnl and source packages. This should be harmless on other OSs.
|
||||
dnl
|
||||
if test -d /usr/pkg/include -a -d /usr/pkg/lib ; then
|
||||
CFLAGS="$CFLAGS -I/usr/pkg/include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(nsl, gethostname, [
|
||||
LIBS="-lnsl $LIBS"
|
||||
AC_DEFINE(HAVE_LIBNSL) ], [])
|
||||
|
||||
AC_CHECK_LIB(c, socket, [:], [
|
||||
AC_CHECK_LIB(socket, socket, [
|
||||
LIBS="-lsocket $LIBS"
|
||||
AC_DEFINE(HAVE_LIBSOCKET) ], []) ])
|
||||
|
||||
AC_CHECK_LIB(c, gethostbyaddr, [:], [
|
||||
AC_CHECK_LIB(nsl, gethostbyaddr, [
|
||||
LIBS="-lnsl $LIBS"
|
||||
AC_DEFINE(HAVE_LIBNSL) ], []) ])
|
||||
|
||||
AC_CHECK_LIB(c, dlopen, [
|
||||
# fake it
|
||||
AC_DEFINE(HAVE_LIBDL) ], [
|
||||
AC_CHECK_LIB(dl, dlopen, [
|
||||
LIBS="-ldl $LIBS"
|
||||
AC_DEFINE(HAVE_LIBDL) ], []) ])
|
||||
|
||||
dnl The sin may be in a library which need not be specifed
|
||||
dnl as well as res_search resides in libsocket
|
||||
AC_CHECK_LIB(c, sin, [:], [
|
||||
AC_CHECK_LIB(m, sin) ])
|
||||
|
||||
dnl The res_search may be in libsocket as well, and if it is
|
||||
dnl make sure to check for dn_skipname in libresolv, or if res_search
|
||||
dnl is in neither of these libs, still check for dn_skipname in libresolv
|
||||
AC_CHECK_LIB(socket, res_search, [
|
||||
AC_CHECK_LIB(resolv, dn_skipname)
|
||||
AC_CHECK_LIB(resolv, __dn_skipname)
|
||||
LIBS="$LIBS -lsocket"
|
||||
AC_DEFINE(HAVE_LIBSOCKET)
|
||||
], [
|
||||
AC_CHECK_LIB(resolv, res_search, [
|
||||
LIBS="$LIBS -lresolv"
|
||||
AC_DEFINE(HAVE_LIBRESOLV)
|
||||
], [
|
||||
AC_CHECK_LIB(resolv, dn_skipname)
|
||||
AC_CHECK_LIB(resolv, __dn_skipname)
|
||||
])
|
||||
])
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
|
||||
dnl In QNX opendir resides in libc but dirent.h is still required
|
||||
if test "`uname -s 2>/dev/null`" != "QNX"; then
|
||||
AC_HEADER_DIRENT
|
||||
else
|
||||
AC_CHECK_HEADERS(dirent.h)
|
||||
fi
|
||||
dnl QNX requires unix.h to allow functions in libunix to work properly
|
||||
AC_CHECK_HEADERS(fcntl.h unistd.h crypt.h sys/file.h memory.h pwd.h grp.h sys/socket.h sys/wait.h syslog.h string.h sys/varargs.h stdarg.h sys/resource.h sys/time.h signal.h netinet/in.h dlfcn.h limits.h sys/types.h sys/statvfs.h sys/statfs.h unix.h db.h ndbm.h)
|
||||
|
||||
dnl Checks for types
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
dnl This is required for QNX and may be some BSD derived systems
|
||||
AC_CHECK_TYPE( uint, unsigned int )
|
||||
AC_CHECK_TYPE( ulong, unsigned long )
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(memcpy memmove strdup strerror strcasecmp strstr flock lockf putenv tempnam usleep setlocale gettimeofday setvbuf srand48 lrand48 srandom random link symlink regcomp getlogin cuserid vsnprintf snprintf gcvt utime crypt setitimer rint unsetenv strftime setsockopt tzset statvfs statfs inet_aton)
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_FUNC_ALLOCA
|
||||
AC_BROKEN_SPRINTF
|
||||
AC_REPLACE_FUNCS(getopt)
|
||||
|
||||
AC_MSG_CHECKING(whether to include debugging symbols)
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Compile with debugging symbols],
|
||||
[
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(ZEND_DEBUG,1)
|
||||
DEBUG_CFLAGS="-g"
|
||||
test -n "$GCC" && DEBUG_CFLAGS="$DEBUG_CFLAGS -Wall"
|
||||
test -n "$GCC" && test "$USE_MAINTAINER_MODE" = "yes" && \
|
||||
DEBUG_CFLAGS="$DEBUG_CFLAGS -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations"
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(ZEND_DEBUG,0)
|
||||
DEBUG_CFLAGS=""
|
||||
fi
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(ZEND_DEBUG,0)
|
||||
DEBUG_CFLAGS=""
|
||||
])
|
||||
AC_SUBST(DEBUG_CFLAGS)
|
||||
|
||||
|
||||
AC_MSG_CHECKING(whether to enable a memory limit)
|
||||
AC_ARG_ENABLE(memory-limit,
|
||||
[ --enable-memory-limit Compile with memory limit support. ],
|
||||
[
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_DEFINE(MEMORY_LIMIT, 1)
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_DEFINE(MEMORY_LIMIT, 0)
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
],[
|
||||
AC_DEFINE(MEMORY_LIMIT, 0)
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
|
||||
AC_SUBST(CFLAGS_SHLIB)
|
||||
AC_SUBST(LDFLAGS_SHLIB)
|
||||
AC_SUBST(LDFLAGS_SHLIB_EXPORT)
|
||||
|
||||
AC_OUTPUT(Makefile, [], [])
|
||||
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 4
|
||||
# End:
|
||||
@@ -0,0 +1,8 @@
|
||||
Index: zend_execute.c
|
||||
===================================================================
|
||||
RCS file: /repository/Zend/ZendCore/zend_execute.c,v
|
||||
retrieving revision 1.25
|
||||
retrieving revision 1.26
|
||||
diff -r1.25 -r1.26
|
||||
17d16
|
||||
< /* $Id$ */
|
||||
@@ -0,0 +1,632 @@
|
||||
%{
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
* LALR shift/reduce conflicts and how they are resolved:
|
||||
*
|
||||
* - 2 shift/reduce conflicts due to the dangeling elseif/else ambiguity. Solved by shift.
|
||||
* - 1 shift/reduce conflict due to arrays within encapsulated strings. Solved by shift.
|
||||
* - 1 shift/reduce conflict due to objects within encapsulated strings. Solved by shift.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "zend_compile.h"
|
||||
#include "zend.h"
|
||||
#include "zend_list.h"
|
||||
#include "zend_globals.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_operators.h"
|
||||
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
|
||||
%}
|
||||
|
||||
%pure_parser
|
||||
%expect 4
|
||||
|
||||
%left INCLUDE EVAL
|
||||
%left ','
|
||||
%left LOGICAL_OR
|
||||
%left LOGICAL_XOR
|
||||
%left LOGICAL_AND
|
||||
%right ZEND_PRINT
|
||||
%left '=' PLUS_EQUAL MINUS_EQUAL MUL_EQUAL DIV_EQUAL CONCAT_EQUAL MOD_EQUAL AND_EQUAL OR_EQUAL XOR_EQUAL SHIFT_LEFT_EQUAL SHIFT_RIGHT_EQUAL
|
||||
%left '?' ':'
|
||||
%left BOOLEAN_OR
|
||||
%left BOOLEAN_AND
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%nonassoc IS_EQUAL IS_NOT_EQUAL
|
||||
%nonassoc '<' IS_SMALLER_OR_EQUAL '>' IS_GREATER_OR_EQUAL
|
||||
%left SHIFT_LEFT SHIFT_RIGHT
|
||||
%left '+' '-' '.'
|
||||
%left '*' '/' '%'
|
||||
%right '!' '~' INCREMENT DECREMENT INT_CAST DOUBLE_CAST STRING_CAST ARRAY_CAST OBJECT_CAST '@'
|
||||
%right '['
|
||||
%nonassoc NEW
|
||||
%token T_EXIT
|
||||
%token IF
|
||||
%left ELSEIF
|
||||
%left ELSE
|
||||
%left ENDIF
|
||||
%token LNUMBER
|
||||
%token DNUMBER
|
||||
%token STRING
|
||||
%token VARIABLE
|
||||
%token NUM_STRING
|
||||
%token INLINE_HTML
|
||||
%token CHARACTER
|
||||
%token BAD_CHARACTER
|
||||
%token ENCAPSED_AND_WHITESPACE
|
||||
%token CONSTANT_ENCAPSED_STRING
|
||||
%token ZEND_ECHO
|
||||
%token DO
|
||||
%token WHILE
|
||||
%token ENDWHILE
|
||||
%token FOR
|
||||
%token ENDFOR
|
||||
%token ZEND_FOREACH
|
||||
%token T_ENDFOREACH
|
||||
%token ZEND_AS
|
||||
%token SWITCH
|
||||
%token ENDSWITCH
|
||||
%token CASE
|
||||
%token DEFAULT
|
||||
%token BREAK
|
||||
%token CONTINUE
|
||||
%token CONTINUED_WHILE
|
||||
%token CONTINUED_DOWHILE
|
||||
%token CONTINUED_FOR
|
||||
%token OLD_FUNCTION
|
||||
%token FUNCTION
|
||||
%token ZEND_CONST
|
||||
%token RETURN
|
||||
%token REQUIRE
|
||||
%token ZEND_GLOBAL
|
||||
%token ZEND_STATIC
|
||||
%token ZEND_UNSET
|
||||
%token T_ISSET
|
||||
%token T_EMPTY
|
||||
%token CLASS
|
||||
%token EXTENDS
|
||||
%token ZEND_OBJECT_OPERATOR
|
||||
%token ZEND_DOUBLE_ARROW
|
||||
%token ZEND_LIST
|
||||
%token ZEND_ARRAY
|
||||
%token VAR
|
||||
%token ZEND_LINE
|
||||
%token ZEND_FILE
|
||||
%token ZEND_COMMENT
|
||||
%token ZEND_ML_COMMENT
|
||||
%token PHP_OPEN_TAG
|
||||
%token PHP_OPEN_TAG_WITH_ECHO
|
||||
%token PHP_CLOSE_TAG
|
||||
%token T_WHITESPACE
|
||||
%token ZEND_HEREDOC
|
||||
%token DOLLAR_OPEN_CURLY_BRACES
|
||||
%token T_CURLY_OPEN
|
||||
%token T_PAAMAYIM_NEKUDOTAYIM
|
||||
%token T_PHP_TRACK_VARS
|
||||
|
||||
%% /* Rules */
|
||||
|
||||
statement_list:
|
||||
statement_list { do_extended_info(CLS_C); } statement { HANDLE_INTERACTIVE(); }
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
|
||||
statement:
|
||||
'{' statement_list '}'
|
||||
| IF '(' expr ')' { do_if_cond(&$3, &$4 CLS_CC); } statement { do_if_after_statement(&$4, 1 CLS_CC); } elseif_list else_single { do_if_end(CLS_C); }
|
||||
| IF '(' expr ')' ':' { do_if_cond(&$3, &$4 CLS_CC); } statement_list { do_if_after_statement(&$4, 1 CLS_CC); } new_elseif_list new_else_single ENDIF ';' { do_if_end(CLS_C); }
|
||||
| WHILE '(' { $1.u.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' { do_while_cond(&$4, &$5 CLS_CC); } while_statement { do_while_end(&$1, &$5 CLS_CC); }
|
||||
| DO { $1.u.opline_num = get_next_op_number(CG(active_op_array)); do_do_while_begin(CLS_C); } statement WHILE '(' expr ')' ';' { do_do_while_end(&$1, &$6 CLS_CC); }
|
||||
| FOR
|
||||
'('
|
||||
for_expr
|
||||
';' { do_free(&$3 CLS_CC); $4.u.opline_num = get_next_op_number(CG(active_op_array)); }
|
||||
for_expr
|
||||
';' { do_for_cond(&$6, &$7 CLS_CC); }
|
||||
for_expr
|
||||
')' { do_free(&$9 CLS_CC); do_for_before_statement(&$4, &$7 CLS_CC); }
|
||||
for_statement { do_for_end(&$7 CLS_CC); }
|
||||
| SWITCH '(' expr ')' { do_switch_cond(&$3 CLS_CC); } switch_case_list { do_switch_end(&$6 CLS_CC); }
|
||||
| BREAK ';' { do_brk_cont(ZEND_BRK, NULL CLS_CC); }
|
||||
| BREAK expr ';' { do_brk_cont(ZEND_BRK, &$2 CLS_CC); }
|
||||
| CONTINUE ';' { do_brk_cont(ZEND_CONT, NULL CLS_CC); }
|
||||
| CONTINUE expr ';' { do_brk_cont(ZEND_CONT, &$2 CLS_CC); }
|
||||
| FUNCTION { $1.u.opline_num = CG(zend_lineno); } STRING { do_begin_function_declaration(&$1, &$3, 0 CLS_CC); }
|
||||
'(' parameter_list ')' '{' statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
|
||||
| OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } STRING { do_begin_function_declaration(&$1, &$3, 0 CLS_CC); }
|
||||
parameter_list '(' statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); }
|
||||
| RETURN ';' { do_return(NULL CLS_CC); }
|
||||
| RETURN expr ';' { do_return(&$2 CLS_CC); }
|
||||
| ZEND_GLOBAL global_var_list
|
||||
| ZEND_STATIC static_var_list
|
||||
| CLASS STRING { do_begin_class_declaration(&$2, NULL CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); }
|
||||
| CLASS STRING EXTENDS STRING { do_begin_class_declaration(&$2, &$4 CLS_CC); } '{' class_statement_list '}' { do_end_class_declaration(CLS_C); }
|
||||
| ZEND_ECHO echo_expr_list ';'
|
||||
| INLINE_HTML { do_echo(&$1 CLS_CC); }
|
||||
| expr ';' { do_free(&$1 CLS_CC); }
|
||||
| REQUIRE CONSTANT_ENCAPSED_STRING ';' { require_filename($2.u.constant.value.str.val CLS_CC); zval_dtor(&$2.u.constant); }
|
||||
| REQUIRE '(' CONSTANT_ENCAPSED_STRING ')' ';' { require_filename($3.u.constant.value.str.val CLS_CC); zval_dtor(&$3.u.constant); }
|
||||
| ZEND_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); }
|
||||
| ZEND_FOREACH '(' expr ZEND_AS { do_foreach_begin(&$1, &$3, &$2, &$4); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
|
||||
| ';' /* empty statement */
|
||||
;
|
||||
|
||||
|
||||
foreach_optional_arg:
|
||||
/* empty */ { $$.op_type = IS_UNUSED; }
|
||||
| ZEND_DOUBLE_ARROW w_cvar { $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
for_statement:
|
||||
statement
|
||||
| ':' statement_list ENDFOR ';'
|
||||
;
|
||||
|
||||
|
||||
foreach_statement:
|
||||
statement
|
||||
| ':' statement_list T_ENDFOREACH ';'
|
||||
;
|
||||
|
||||
|
||||
switch_case_list:
|
||||
'{' case_list '}' { $$ = $2; }
|
||||
| '{' ';' case_list '}' { $$ = $3; }
|
||||
| ':' case_list ENDSWITCH ';' { $$ = $2; }
|
||||
| ':' ';' case_list ENDSWITCH ';' { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
case_list:
|
||||
/* empty */ { $$.u.opline_num = -1; }
|
||||
| case_list CASE expr case_separator { do_case_before_statement(&$1, &$2, &$3 CLS_CC); } statement_list { do_case_after_statement(&$$, &$2 CLS_CC); }
|
||||
| case_list DEFAULT case_separator { do_default_before_statement(&$1, &$2 CLS_CC); } statement_list { do_case_after_statement(&$$, &$2 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
case_separator:
|
||||
':'
|
||||
| ';'
|
||||
;
|
||||
|
||||
|
||||
while_statement:
|
||||
statement
|
||||
| ':' statement_list ENDWHILE ';'
|
||||
;
|
||||
|
||||
|
||||
|
||||
elseif_list:
|
||||
/* empty */
|
||||
| elseif_list ELSEIF '(' expr ')' { do_if_cond(&$4, &$5 CLS_CC); } statement { do_if_after_statement(&$5, 0 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
new_elseif_list:
|
||||
/* empty */
|
||||
| new_elseif_list ELSEIF '(' expr ')' ':' { do_if_cond(&$4, &$5 CLS_CC); } statement_list { do_if_after_statement(&$5, 0 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
else_single:
|
||||
/* empty */
|
||||
| ELSE statement
|
||||
;
|
||||
|
||||
|
||||
new_else_single:
|
||||
/* empty */
|
||||
| ELSE ':' statement_list
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
parameter_list:
|
||||
non_empty_parameter_list
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
|
||||
non_empty_parameter_list:
|
||||
VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
|
||||
| '&' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
|
||||
| ZEND_CONST VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
|
||||
| VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=0; $$.u.constant.type=IS_LONG; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$3, BYREF_NONE CLS_CC); }
|
||||
| non_empty_parameter_list ',' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
|
||||
| non_empty_parameter_list ',' '&' VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
|
||||
| non_empty_parameter_list ',' ZEND_CONST VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
|
||||
| non_empty_parameter_list ',' VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, BYREF_NONE CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
function_call_parameter_list:
|
||||
non_empty_function_call_parameter_list
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
|
||||
non_empty_function_call_parameter_list:
|
||||
expr_without_variable { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
|
||||
| cvar { $$.u.constant.value.lval = 0; do_pass_param(&$1, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
|
||||
| '&' w_cvar { $$.u.constant.value.lval = 0; do_pass_param(&$2, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
|
||||
| non_empty_function_call_parameter_list ',' expr_without_variable { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAL, $$.u.constant.value.lval CLS_CC); }
|
||||
| non_empty_function_call_parameter_list ',' cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$3, ZEND_SEND_VAR, $$.u.constant.value.lval CLS_CC); }
|
||||
| non_empty_function_call_parameter_list ',' '&' w_cvar { $$.u.constant.value.lval=$1.u.constant.value.lval+1; do_pass_param(&$4, ZEND_SEND_REF, $$.u.constant.value.lval CLS_CC); }
|
||||
;
|
||||
|
||||
global_var_list:
|
||||
global_var_list ',' global_var { do_fetch_global_or_static_variable(&$3, NULL, ZEND_FETCH_GLOBAL CLS_CC); }
|
||||
| global_var { do_fetch_global_or_static_variable(&$1, NULL, ZEND_FETCH_GLOBAL CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
global_var:
|
||||
VARIABLE { $$ = $1; }
|
||||
| '$' r_cvar { $$ = $2; }
|
||||
| '$' '{' expr '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
static_var_list:
|
||||
static_var_list ',' VARIABLE { do_fetch_global_or_static_variable(&$3, NULL, ZEND_FETCH_STATIC CLS_CC); }
|
||||
| static_var_list ',' VARIABLE '=' static_scalar { do_fetch_global_or_static_variable(&$3, &$5, ZEND_FETCH_STATIC CLS_CC); }
|
||||
| VARIABLE { do_fetch_global_or_static_variable(&$1, NULL, ZEND_FETCH_STATIC CLS_CC); }
|
||||
| VARIABLE '=' static_scalar { do_fetch_global_or_static_variable(&$1, &$3, ZEND_FETCH_STATIC CLS_CC); }
|
||||
|
||||
;
|
||||
|
||||
|
||||
class_statement_list:
|
||||
class_statement_list class_statement
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
|
||||
class_statement:
|
||||
VAR class_variable_decleration ';'
|
||||
| FUNCTION { $1.u.opline_num = CG(zend_lineno); } STRING { do_begin_function_declaration(&$1, &$3, 1 CLS_CC); } '('
|
||||
parameter_list ')' '{' statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
|
||||
| OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } STRING { do_begin_function_declaration(&$1, &$3, 1 CLS_CC); }
|
||||
parameter_list '(' statement_list ')' ';' { do_end_function_declaration(&$1 CLS_CC); }
|
||||
|
||||
;
|
||||
|
||||
|
||||
class_variable_decleration:
|
||||
class_variable_decleration ',' VARIABLE { do_declare_property(&$3, NULL CLS_CC); }
|
||||
| class_variable_decleration ',' VARIABLE '=' static_scalar { do_declare_property(&$3, &$5 CLS_CC); }
|
||||
| VARIABLE { do_declare_property(&$1, NULL CLS_CC); }
|
||||
| VARIABLE '=' static_scalar { do_declare_property(&$1, &$3 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
echo_expr_list:
|
||||
/* empty */
|
||||
| echo_expr_list ',' expr { do_echo(&$3 CLS_CC); }
|
||||
| expr { do_echo(&$1 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
for_expr:
|
||||
/* empty */ { $$.op_type = IS_CONST; $$.u.constant.type = IS_BOOL; $$.u.constant.value.lval = 1; }
|
||||
| for_expr ',' expr { $$ = $3; }
|
||||
| expr { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
expr_without_variable:
|
||||
ZEND_LIST '(' { do_list_init(); } assignment_list ')' '=' expr { do_list_end(&$$, &$7 CLS_CC); }
|
||||
| w_cvar '=' expr { do_assign(&$$, &$1, &$3 CLS_CC); }
|
||||
| w_cvar '=' '&' w_cvar { do_assign_ref(&$$, &$1, &$4 CLS_CC); }
|
||||
| w_cvar '=' NEW class_name { do_extended_fcall_begin(CLS_C); do_begin_new_object(&$2, &$1, &$3, &$4 CLS_CC); } ctor_arguments { do_end_new_object(&$4, &$3 CLS_CC); do_extended_fcall_end(CLS_C); $$ = $2;}
|
||||
| rw_cvar PLUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar MINUS_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SUB, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar MUL_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MUL, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar DIV_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_DIV, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar CONCAT_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_CONCAT, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar MOD_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_MOD, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar AND_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar OR_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar XOR_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar SHIFT_LEFT_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar SHIFT_RIGHT_EQUAL expr { do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 CLS_CC); }
|
||||
| rw_cvar INCREMENT { do_post_incdec(&$$, &$1, ZEND_POST_INC CLS_CC); }
|
||||
| INCREMENT rw_cvar { do_pre_incdec(&$$, &$2, ZEND_PRE_INC CLS_CC); }
|
||||
| rw_cvar DECREMENT { do_post_incdec(&$$, &$1, ZEND_POST_DEC CLS_CC); }
|
||||
| DECREMENT rw_cvar { do_pre_incdec(&$$, &$2, ZEND_PRE_DEC CLS_CC); }
|
||||
| expr BOOLEAN_OR { do_boolean_or_begin(&$1, &$2 CLS_CC); } expr { do_boolean_or_end(&$$, &$1, &$4, &$2 CLS_CC); }
|
||||
| expr BOOLEAN_AND { do_boolean_and_begin(&$1, &$2 CLS_CC); } expr { do_boolean_and_end(&$$, &$1, &$4, &$2 CLS_CC); }
|
||||
| expr LOGICAL_OR { do_boolean_or_begin(&$1, &$2 CLS_CC); } expr { do_boolean_or_end(&$$, &$1, &$4, &$2 CLS_CC); }
|
||||
| expr LOGICAL_AND { do_boolean_and_begin(&$1, &$2 CLS_CC); } expr { do_boolean_and_end(&$$, &$1, &$4, &$2 CLS_CC); }
|
||||
| expr LOGICAL_XOR expr { do_binary_op(ZEND_BOOL_XOR, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '|' expr { do_binary_op(ZEND_BW_OR, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '&' expr { do_binary_op(ZEND_BW_AND, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '^' expr { do_binary_op(ZEND_BW_XOR, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '.' expr { do_binary_op(ZEND_CONCAT,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr '+' expr { do_binary_op(ZEND_ADD,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr '-' expr { do_binary_op(ZEND_SUB,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr '*' expr { do_binary_op(ZEND_MUL,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr '/' expr { do_binary_op(ZEND_DIV,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr '%' expr { do_binary_op(ZEND_MOD,&$$,&$1,&$3 CLS_CC); }
|
||||
| expr SHIFT_LEFT expr { do_binary_op(ZEND_SL, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr SHIFT_RIGHT expr { do_binary_op(ZEND_SR, &$$, &$1, &$3 CLS_CC); }
|
||||
| '+' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG; $1.op_type = IS_CONST; $1.u.constant.refcount=1; do_binary_op(ZEND_ADD, &$$, &$1, &$2 CLS_CC); }
|
||||
| '-' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG; $1.op_type = IS_CONST; $1.u.constant.refcount=1; do_binary_op(ZEND_SUB, &$$, &$1, &$2 CLS_CC); }
|
||||
| '!' expr { do_unary_op(ZEND_BOOL_NOT, &$$, &$2 CLS_CC); }
|
||||
| '~' expr { do_unary_op(ZEND_BW_NOT, &$$, &$2 CLS_CC); }
|
||||
| expr IS_EQUAL expr { do_binary_op(ZEND_IS_EQUAL, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr IS_NOT_EQUAL expr { do_binary_op(ZEND_IS_NOT_EQUAL, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '<' expr { do_binary_op(ZEND_IS_SMALLER, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr IS_SMALLER_OR_EQUAL expr { do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3 CLS_CC); }
|
||||
| expr '>' expr { do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 CLS_CC); }
|
||||
| expr IS_GREATER_OR_EQUAL expr { do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 CLS_CC); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| expr '?' { do_begin_qm_op(&$1, &$2 CLS_CC); }
|
||||
expr ':' { do_qm_true(&$4, &$2, &$5 CLS_CC); }
|
||||
expr { do_qm_false(&$$, &$7, &$2, &$5 CLS_CC); }
|
||||
| STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_function_call(&$1 CLS_CC); }
|
||||
function_call_parameter_list
|
||||
')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C); }
|
||||
| r_cvar '(' { do_extended_fcall_begin(CLS_C); do_begin_dynamic_function_call(&$1 CLS_CC); }
|
||||
function_call_parameter_list
|
||||
')' { do_end_function_call(&$1, &$$, 0 CLS_CC); do_extended_fcall_end(CLS_C);}
|
||||
| STRING T_PAAMAYIM_NEKUDOTAYIM STRING '(' { do_extended_fcall_begin(CLS_C); do_begin_class_member_function_call(&$1, &$3 CLS_CC); }
|
||||
function_call_parameter_list
|
||||
')' { do_end_function_call(&$3, &$$, 1 CLS_CC); do_extended_fcall_end(CLS_C);}
|
||||
| internal_functions_in_yacc { $$ = $1; }
|
||||
| INT_CAST expr { do_cast(&$$, &$2, IS_LONG CLS_CC); }
|
||||
| DOUBLE_CAST expr { do_cast(&$$, &$2, IS_DOUBLE CLS_CC); }
|
||||
| STRING_CAST expr { do_cast(&$$, &$2, IS_STRING CLS_CC); }
|
||||
| ARRAY_CAST expr { do_cast(&$$, &$2, IS_ARRAY CLS_CC); }
|
||||
| OBJECT_CAST expr { do_cast(&$$, &$2, IS_OBJECT CLS_CC); }
|
||||
| T_EXIT exit_expr { do_exit(&$$, &$2 CLS_CC); }
|
||||
| '@' { do_begin_silence(&$1 CLS_CC); } expr { do_end_silence(&$1 CLS_CC); $$ = $3; }
|
||||
| scalar { $$ = $1; }
|
||||
| ZEND_ARRAY '(' array_pair_list ')' { $$ = $3; }
|
||||
| '`' encaps_list '`' { do_shell_exec(&$$, &$2 CLS_CC); }
|
||||
| ZEND_PRINT expr { do_print(&$$, &$2 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
exit_expr:
|
||||
/* empty */ { $$.op_type = IS_UNUSED; }
|
||||
| '(' ')' { $$.op_type = IS_UNUSED; }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
ctor_arguments:
|
||||
/* empty */
|
||||
| '(' function_call_parameter_list ')'
|
||||
;
|
||||
|
||||
|
||||
class_name:
|
||||
STRING { $$ = $1; }
|
||||
| r_cvar { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
common_scalar:
|
||||
LNUMBER { $$=$1; }
|
||||
| DNUMBER { $$=$1; }
|
||||
| CONSTANT_ENCAPSED_STRING { $$ = $1; }
|
||||
| ZEND_LINE
|
||||
| ZEND_FILE
|
||||
;
|
||||
|
||||
|
||||
static_scalar: /* compile-time evaluated scalars */
|
||||
common_scalar { $$ = $1; }
|
||||
| STRING { do_fetch_constant(&$$, &$1, ZEND_CT CLS_CC); }
|
||||
| '+' static_scalar { $$ = $1; }
|
||||
| '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one); $$ = $2; }
|
||||
| ZEND_ARRAY '(' static_array_pair_list ')' { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
scalar:
|
||||
STRING { do_fetch_constant(&$$, &$1, ZEND_RT CLS_CC); }
|
||||
| common_scalar { $$ = $1; }
|
||||
| '"' encaps_list '"' { $$ = $2; }
|
||||
| '\'' encaps_list '\'' { $$ = $2; }
|
||||
| ZEND_HEREDOC encaps_list ZEND_HEREDOC { $$ = $2; do_end_heredoc(CLS_C); }
|
||||
;
|
||||
|
||||
|
||||
static_array_pair_list:
|
||||
/* empty */ { $$.op_type = IS_CONST; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; array_init(&$$.u.constant); }
|
||||
| non_empty_static_array_pair_list { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
non_empty_static_array_pair_list:
|
||||
non_empty_static_array_pair_list ',' static_scalar ZEND_DOUBLE_ARROW static_scalar { do_add_static_array_element(&$$, &$3, &$5); }
|
||||
| non_empty_static_array_pair_list ',' static_scalar { do_add_static_array_element(&$$, &$3, NULL); }
|
||||
| static_scalar ZEND_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; array_init(&$$.u.constant); do_add_static_array_element(&$$, &$1, &$3); }
|
||||
| static_scalar { $$.op_type = IS_CONST; $$.u.constant.refcount=1; $$.u.constant.is_ref=0; array_init(&$$.u.constant); do_add_static_array_element(&$$, &$1, NULL); }
|
||||
;
|
||||
|
||||
expr:
|
||||
r_cvar { $$ = $1; }
|
||||
| expr_without_variable { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
r_cvar:
|
||||
cvar { do_end_variable_parse(BP_VAR_R CLS_CC); $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
w_cvar:
|
||||
cvar { do_end_variable_parse(BP_VAR_W CLS_CC); $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
rw_cvar:
|
||||
cvar { do_end_variable_parse(BP_VAR_RW CLS_CC); $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
cvar:
|
||||
cvar_without_objects { $$ = $1; }
|
||||
| cvar_without_objects ZEND_OBJECT_OPERATOR { do_push_object(&$1 CLS_CC); } ref_list { $$ = $4; }
|
||||
;
|
||||
|
||||
|
||||
cvar_without_objects:
|
||||
reference_variable { $$ = $1; }
|
||||
| simple_indirect_reference reference_variable { do_indirect_references(&$$, &$1, &$2 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
reference_variable:
|
||||
dim_list ']' { $$ = $1; }
|
||||
| compound_variable { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
compound_variable:
|
||||
VARIABLE { $$ = $1; }
|
||||
| '$' '{' expr '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
|
||||
dim_list:
|
||||
dim_list ']' '[' dim_offset { fetch_array_dim(&$$, &$1, &$4 CLS_CC); }
|
||||
| compound_variable { do_begin_variable_parse(CLS_C); } '[' dim_offset { fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
dim_offset:
|
||||
/* empty */ { $$.op_type = IS_UNUSED; }
|
||||
| expr { $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
ref_list:
|
||||
object_property { $$ = $1; }
|
||||
| ref_list ZEND_OBJECT_OPERATOR { do_push_object(&$1 CLS_CC); } object_property { $$ = $4; }
|
||||
;
|
||||
|
||||
object_property:
|
||||
scalar_object_property { znode tmp_znode; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&$$, &tmp_znode, &$1 CLS_CC); }
|
||||
| object_dim_list ']' { $$ = $1; }
|
||||
;
|
||||
|
||||
scalar_object_property:
|
||||
STRING { $$ = $1; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| cvar_without_objects { do_end_variable_parse(BP_VAR_R CLS_CC); $$ = $1; }
|
||||
;
|
||||
|
||||
|
||||
object_dim_list:
|
||||
object_dim_list ']' '[' expr { fetch_array_dim(&$$, &$1, &$4 CLS_CC); }
|
||||
| STRING { znode tmp_znode, res; do_pop_object(&tmp_znode CLS_CC); do_fetch_property(&res, &tmp_znode, &$1 CLS_CC); $1 = res; } '[' expr { fetch_array_dim(&$$, &$1, &$4 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
simple_indirect_reference:
|
||||
'$' { $$.u.constant.value.lval = 1; }
|
||||
| simple_indirect_reference '$' { $$.u.constant.value.lval++; }
|
||||
;
|
||||
|
||||
assignment_list:
|
||||
assignment_list ',' assignment_list_element
|
||||
| assignment_list_element
|
||||
;
|
||||
|
||||
|
||||
assignment_list_element:
|
||||
w_cvar { do_add_list_element(&$1 CLS_CC); }
|
||||
| ZEND_LIST '(' { do_new_list_begin(CLS_C); } assignment_list ')' { do_new_list_end(CLS_C); }
|
||||
| /* empty */ { do_add_list_element(NULL CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
array_pair_list:
|
||||
/* empty */ { do_init_array(&$$, NULL, NULL CLS_CC); }
|
||||
| non_empty_array_pair_list { $$ = $1; }
|
||||
;
|
||||
|
||||
non_empty_array_pair_list:
|
||||
non_empty_array_pair_list ',' expr ZEND_DOUBLE_ARROW expr { do_add_array_element(&$$, &$5, &$3 CLS_CC); }
|
||||
| non_empty_array_pair_list ',' expr { do_add_array_element(&$$, &$3, NULL CLS_CC); }
|
||||
| expr ZEND_DOUBLE_ARROW expr { do_init_array(&$$, &$3, &$1 CLS_CC); }
|
||||
| expr { do_init_array(&$$, &$1, NULL CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
encaps_list:
|
||||
encaps_list encaps_var { do_end_variable_parse(BP_VAR_R CLS_CC); do_add_variable(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list STRING { do_add_string(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list NUM_STRING { do_add_string(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list ENCAPSED_AND_WHITESPACE { do_add_string(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list CHARACTER { do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list BAD_CHARACTER { do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list '[' { $2.u.constant.value.chval = '['; do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list ']' { $2.u.constant.value.chval = ']'; do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list '{' { $2.u.constant.value.chval = '{'; do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list '}' { $2.u.constant.value.chval = '}'; do_add_char(&$$, &$1, &$2 CLS_CC); }
|
||||
| encaps_list ZEND_OBJECT_OPERATOR { znode tmp; $2.u.constant.value.chval = '-'; do_add_char(&tmp, &$1, &$2 CLS_CC); $2.u.constant.value.chval = '>'; do_add_char(&$$, &tmp, &$2 CLS_CC); }
|
||||
| /* empty */ { do_init_string(&$$); }
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
encaps_var:
|
||||
VARIABLE { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
|
||||
| VARIABLE '[' encaps_var_offset ']' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$1, &$3 CLS_CC); }
|
||||
| VARIABLE ZEND_OBJECT_OPERATOR STRING { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$2, &$1, 1 CLS_CC); do_fetch_property(&$$, &$2, &$3 CLS_CC); }
|
||||
| DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
|
||||
| DOLLAR_OPEN_CURLY_BRACES STRING '[' expr ']' '}' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$2, &$4 CLS_CC); }
|
||||
| T_CURLY_OPEN cvar '}' { $$ = $2; }
|
||||
;
|
||||
|
||||
|
||||
encaps_var_offset:
|
||||
STRING { $$ = $1; }
|
||||
| NUM_STRING { $$ = $1; }
|
||||
| { do_begin_variable_parse(CLS_C); } VARIABLE { fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
internal_functions_in_yacc:
|
||||
T_ISSET '(' cvar ')' { do_isset_or_isempty(ZEND_ISSET, &$$, &$3 CLS_CC); }
|
||||
| T_EMPTY '(' cvar ')' { do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 CLS_CC); }
|
||||
| INCLUDE expr { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); }
|
||||
| EVAL '(' expr ')' { do_include_or_eval(ZEND_EVAL, &$$, &$3 CLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _LANGUAGE_SCANNER_H
|
||||
#define _LANGUAGE_SCANNER_H
|
||||
|
||||
typedef struct {
|
||||
YY_BUFFER_STATE buffer_state;
|
||||
int state;
|
||||
uint return_offset;
|
||||
uint lineno;
|
||||
FILE *in;
|
||||
char *filename;
|
||||
} zend_lex_state;
|
||||
|
||||
#endif
|
||||
+1195
File diff suppressed because it is too large.
Load diff
+255
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_extensions.h"
|
||||
#include "modules.h"
|
||||
#include "zend_constants.h"
|
||||
#include "zend_list.h"
|
||||
|
||||
/* true multithread-shared globals */
|
||||
zend_class_entry standard_class;
|
||||
ZEND_API int (*zend_printf)(const char *format, ...);
|
||||
ZEND_API int (*zend_write)(const char *str, uint str_length);
|
||||
ZEND_API void (*zend_error)(int type, const char *format, ...);
|
||||
void (*zend_message_dispatcher)(long message, void *data);
|
||||
FILE *(*zend_fopen)(const char *filename);
|
||||
void (*zend_block_interruptions)();
|
||||
void (*zend_unblock_interruptions)();
|
||||
|
||||
zend_utility_values zend_uv;
|
||||
|
||||
/* version information */
|
||||
static char *zend_version_info;
|
||||
static uint zend_version_info_length;
|
||||
#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski\n"
|
||||
|
||||
|
||||
#define PRINT_PVAL_INDENT 4
|
||||
|
||||
static void print_hash(HashTable *ht, int indent)
|
||||
{
|
||||
zval **tmp;
|
||||
char *string_key;
|
||||
unsigned long num_key;
|
||||
int i;
|
||||
|
||||
for (i=0; i<indent; i++) {
|
||||
ZEND_PUTS(" ");
|
||||
}
|
||||
ZEND_PUTS("(\n");
|
||||
indent += PRINT_PVAL_INDENT;
|
||||
zend_hash_internal_pointer_reset(ht);
|
||||
while (zend_hash_get_current_data(ht, (void **) &tmp) == SUCCESS) {
|
||||
for (i=0; i<indent; i++) {
|
||||
ZEND_PUTS(" ");
|
||||
}
|
||||
ZEND_PUTS("[");
|
||||
switch (zend_hash_get_current_key(ht, &string_key, &num_key)) {
|
||||
case HASH_KEY_IS_STRING:
|
||||
ZEND_PUTS(string_key);
|
||||
break;
|
||||
case HASH_KEY_IS_LONG:
|
||||
zend_printf("%ld",num_key);
|
||||
break;
|
||||
}
|
||||
ZEND_PUTS("] => ");
|
||||
zend_print_zval_r(*tmp, indent+PRINT_PVAL_INDENT);
|
||||
ZEND_PUTS("\n");
|
||||
zend_hash_move_forward(ht);
|
||||
}
|
||||
indent -= PRINT_PVAL_INDENT;
|
||||
for (i=0; i<indent; i++) {
|
||||
ZEND_PUTS(" ");
|
||||
}
|
||||
ZEND_PUTS(")\n");
|
||||
}
|
||||
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent)
|
||||
{
|
||||
zval expr_copy;
|
||||
int destroy=0;
|
||||
|
||||
if (expr->type != IS_STRING) {
|
||||
if (expr->type == IS_BOOL) {
|
||||
if (expr->value.lval) {
|
||||
expr_copy.value.str.val = estrndup("true",4);
|
||||
expr_copy.value.str.len = 4;
|
||||
} else {
|
||||
expr_copy.value.str.val = estrndup("false",5);
|
||||
expr_copy.value.str.len = 5;
|
||||
}
|
||||
expr_copy.type = IS_STRING;
|
||||
} else if (expr->type == IS_RESOURCE) {
|
||||
expr_copy.value.str.val = (char *) emalloc(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG);
|
||||
expr_copy.value.str.len = sprintf(expr_copy.value.str.val, "Resource id #%ld", expr->value.lval);
|
||||
expr_copy.type = IS_STRING;
|
||||
} else {
|
||||
expr_copy = *expr;
|
||||
zval_copy_ctor(&expr_copy);
|
||||
convert_to_string(&expr_copy);
|
||||
}
|
||||
expr = &expr_copy;
|
||||
destroy=1;
|
||||
}
|
||||
if (expr->value.str.len==0) { /* optimize away empty strings */
|
||||
return 0;
|
||||
}
|
||||
ZEND_WRITE(expr->value.str.val,expr->value.str.len);
|
||||
if (destroy) {
|
||||
zval_dtor(expr);
|
||||
}
|
||||
return expr->value.str.len;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_print_zval_r(zval *expr, int indent)
|
||||
{
|
||||
switch(expr->type) {
|
||||
case IS_ARRAY:
|
||||
ZEND_PUTS("Array\n");
|
||||
print_hash(expr->value.ht,indent);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
zend_printf("%s Object\n", expr->value.obj.ce->name);
|
||||
print_hash(expr->value.obj.properties, indent);
|
||||
break;
|
||||
default:
|
||||
zend_print_variable(expr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FILE *zend_fopen_wrapper(const char *filename)
|
||||
{
|
||||
return fopen(filename, "r");
|
||||
}
|
||||
|
||||
|
||||
static void register_standard_class()
|
||||
{
|
||||
standard_class.type = ZEND_INTERNAL_CLASS;
|
||||
standard_class.name_length = sizeof("stdClass") - 1;
|
||||
standard_class.name = zend_strndup("stdClass", standard_class.name_length);
|
||||
standard_class.parent = NULL;
|
||||
zend_hash_init(&standard_class.default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
||||
zend_hash_init(&standard_class.function_table, 0, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
||||
standard_class.handle_function_call = NULL;
|
||||
standard_class.handle_property_get = NULL;
|
||||
standard_class.handle_property_set = NULL;
|
||||
zend_hash_add(CG(class_table), "stdClass", sizeof("stdClass"), &standard_class, sizeof(zend_class_entry), NULL);
|
||||
}
|
||||
|
||||
|
||||
int zend_startup(zend_utility_functions *utility_functions, zend_utility_values *utility_values, char **extensions)
|
||||
{
|
||||
start_memory_manager();
|
||||
|
||||
/* Set up utility functions and values */
|
||||
zend_error = utility_functions->error_function;
|
||||
zend_printf = utility_functions->printf_function;
|
||||
zend_write = utility_functions->write_function;
|
||||
zend_fopen = utility_functions->fopen_function;
|
||||
if (!zend_fopen) {
|
||||
zend_fopen = zend_fopen_wrapper;
|
||||
}
|
||||
zend_message_dispatcher = utility_functions->message_handler;
|
||||
zend_block_interruptions = utility_functions->block_interruptions;
|
||||
zend_unblock_interruptions = utility_functions->unblock_interruptions;
|
||||
zend_compile_files = compile_files;
|
||||
zend_execute = execute;
|
||||
|
||||
zend_uv = *utility_values;
|
||||
zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
|
||||
|
||||
/* set up version */
|
||||
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
|
||||
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO)-1;
|
||||
|
||||
/* Prepare data structures */
|
||||
zend_startup_constants();
|
||||
CG(function_table) = (HashTable *) malloc(sizeof(HashTable));
|
||||
CG(class_table) = (HashTable *) malloc(sizeof(HashTable));
|
||||
zend_hash_init(CG(function_table), 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
||||
zend_hash_init(CG(class_table), 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
|
||||
register_standard_class();
|
||||
zend_hash_init(&module_registry, 50, NULL, (void (*)(void *)) module_destructor, 1);
|
||||
init_resource_plist();
|
||||
zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void zend_shutdown()
|
||||
{
|
||||
destroy_resource_plist();
|
||||
zend_hash_destroy(&list_destructors);
|
||||
zend_hash_destroy(&module_registry);
|
||||
zend_hash_destroy(CG(function_table));
|
||||
free(CG(function_table));
|
||||
zend_hash_destroy(CG(class_table));
|
||||
free(CG(class_table));
|
||||
zend_llist_destroy(&zend_extensions);
|
||||
free(zend_version_info);
|
||||
zend_shutdown_constants();
|
||||
}
|
||||
|
||||
|
||||
/* this should be compatible with the standard zenderror */
|
||||
void zenderror(char *error)
|
||||
{
|
||||
zend_error(E_PARSE, error);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_bailout()
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
longjmp(EG(bailout), FAILURE);
|
||||
}
|
||||
|
||||
|
||||
void zend_append_version_info(zend_extension *extension)
|
||||
{
|
||||
char *new_info;
|
||||
uint new_info_length;
|
||||
|
||||
new_info_length = sizeof(" with v, by \n")
|
||||
+ strlen(extension->name)
|
||||
+ strlen(extension->version)
|
||||
+ strlen(extension->copyright)
|
||||
+ strlen(extension->author);
|
||||
|
||||
new_info = (char *) malloc(new_info_length+1);
|
||||
|
||||
sprintf(new_info, " with %s v%s, %s, by %s\n", extension->name, extension->version, extension->copyright, extension->author);
|
||||
|
||||
zend_version_info = (char *) realloc(zend_version_info, zend_version_info_length+new_info_length+1);
|
||||
strcat(zend_version_info, new_info);
|
||||
zend_version_info_length += new_info_length;
|
||||
free(new_info);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *get_zend_version()
|
||||
{
|
||||
return zend_version_info;
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_H
|
||||
#define _ZEND_H
|
||||
|
||||
#define ZEND_VERSION "0.80A"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* general definitions
|
||||
*/
|
||||
|
||||
#if WINNT||WIN32
|
||||
#include "config.w32.h"
|
||||
#else
|
||||
#include "config.h"
|
||||
#include "config.unix.h"
|
||||
#endif
|
||||
|
||||
#include "zend_errors.h"
|
||||
#include "zend_alloc.h"
|
||||
|
||||
|
||||
#undef SUCCESS
|
||||
#undef FAILURE
|
||||
#define SUCCESS 0
|
||||
#define FAILURE -1 /* this MUST stay a negative number, or it may effect functions! */
|
||||
|
||||
|
||||
#include "zend_hash.h"
|
||||
#include "zend_llist.h"
|
||||
|
||||
|
||||
#define INTERNAL_FUNCTION_PARAMETERS HashTable *ht, zval *return_value, HashTable *list, HashTable *plist
|
||||
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, list, plist
|
||||
|
||||
/*
|
||||
* zval
|
||||
*/
|
||||
typedef struct _zval_struct zval;
|
||||
typedef struct _zend_class_entry zend_class_entry;
|
||||
|
||||
typedef union {
|
||||
long lval; /* long value */
|
||||
double dval; /* double value */
|
||||
struct {
|
||||
char *val;
|
||||
int len;
|
||||
} str;
|
||||
char chval; /* char value */
|
||||
HashTable *ht; /* hash table value */
|
||||
struct {
|
||||
zend_class_entry *ce;
|
||||
HashTable *properties;
|
||||
} obj;
|
||||
} zvalue_value;
|
||||
|
||||
|
||||
struct _zval_struct {
|
||||
/* Variable information */
|
||||
zvalue_value value; /* value */
|
||||
unsigned char type; /* active type */
|
||||
unsigned char is_ref;
|
||||
short refcount;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *fname;
|
||||
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
|
||||
unsigned char *func_arg_types;
|
||||
} function_entry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type; /* read, write or r/w */
|
||||
zval **object;
|
||||
zend_llist elements_list;
|
||||
} zend_property_reference;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type; /* array offset or object proprety */
|
||||
zval element;
|
||||
} zend_overloaded_element;
|
||||
|
||||
|
||||
struct _zend_class_entry {
|
||||
char type;
|
||||
char *name;
|
||||
uint name_length;
|
||||
struct _zend_class_entry *parent;
|
||||
|
||||
HashTable function_table;
|
||||
HashTable default_properties;
|
||||
|
||||
/* handlers */
|
||||
void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
|
||||
zval (*handle_property_get)(zend_property_reference *property_reference);
|
||||
int (*handle_property_set)(zend_property_reference *property_reference, zval *value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*error_function)(int type, const char *format, ...);
|
||||
int (*printf_function)(const char *format, ...);
|
||||
int (*write_function)(const char *str, uint str_length);
|
||||
FILE *(*fopen_function)(const char *filename);
|
||||
void (*message_handler)(long message, void *data);
|
||||
void (*block_interruptions)();
|
||||
void (*unblock_interruptions)();
|
||||
} zend_utility_functions;
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char short_tags;
|
||||
unsigned char asp_tags;
|
||||
} zend_utility_values;
|
||||
|
||||
|
||||
#undef MIN
|
||||
#undef MAX
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
/* data types */
|
||||
#define IS_LONG 1
|
||||
#define IS_DOUBLE 2
|
||||
#define IS_STRING 3
|
||||
#define IS_ARRAY 4
|
||||
#define IS_OBJECT 5
|
||||
#define IS_BC 6 /* for parser internal use only */
|
||||
#define IS_BOOL 7
|
||||
#define IS_RESOURCE 8
|
||||
#define IS_CONSTANT 9
|
||||
#define IS_METHOD 10 /* for overloaded function calls */
|
||||
|
||||
int zend_startup(zend_utility_functions *utility_functions, zend_utility_values *utility_values, char **extensions);
|
||||
void zend_shutdown();
|
||||
ZEND_API void zend_bailout();
|
||||
ZEND_API char *get_zend_version();
|
||||
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent);
|
||||
ZEND_API void zend_print_zval_r(zval *expr, int indent);
|
||||
|
||||
ZEND_API extern char *empty_string;
|
||||
ZEND_API extern char *undefined_variable_string;
|
||||
|
||||
#define STR_FREE(ptr) if (ptr && ptr!=empty_string && ptr!=undefined_variable_string) { efree(ptr); }
|
||||
|
||||
|
||||
/* output support */
|
||||
#define ZEND_WRITE(str, str_len) zend_write((str), (str_len))
|
||||
#define ZEND_PUTS(str) zend_write((str), strlen((str)))
|
||||
#define ZEND_PUTC(c) zend_write(&(c), 1), (c)
|
||||
|
||||
extern ZEND_API int (*zend_printf)(const char *format, ...);
|
||||
extern ZEND_API int (*zend_write)(const char *str, uint str_length);
|
||||
extern ZEND_API void (*zend_error)(int type, const char *format, ...);
|
||||
extern FILE *(*zend_fopen)(const char *filename);
|
||||
extern void (*zend_message_dispatcher)(long message, void *data);
|
||||
extern void (*zend_block_interruptions)();
|
||||
extern void (*zend_unblock_interruptions)();
|
||||
|
||||
|
||||
void zenderror(char *error);
|
||||
|
||||
extern zend_class_entry standard_class;
|
||||
extern zend_utility_values zend_uv;
|
||||
|
||||
#define ZEND_UV(name) (zend_uv.name)
|
||||
|
||||
|
||||
#define HANDLE_BLOCK_INTERRUPTIONS() if (zend_block_interruptions) { zend_block_interruptions(); }
|
||||
#define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
|
||||
|
||||
|
||||
|
||||
|
||||
/* Messages for applications of Zend */
|
||||
#define ZMSG_ENABLE_TRACK_VARS 1L
|
||||
#define ZMSG_FAILED_INCLUDE_FOPEN 2L
|
||||
#define ZMSG_FAILED_REQUIRE_FOPEN 3L
|
||||
#define ZMSG_FAILED_HIGHLIGHT_FOPEN 4L
|
||||
#define ZMSG_MEMORY_LEAK_DETECTED 5L
|
||||
|
||||
#endif /* _ZEND_H */
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
+701
@@ -0,0 +1,701 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_execute.h"
|
||||
#include "zend_API.h"
|
||||
#include "modules.h"
|
||||
#include "zend_constants.h"
|
||||
#include "zend_operators.h"
|
||||
|
||||
#if HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
/* these variables are true statics/globals, and have to be mutex'ed on every access */
|
||||
static int module_count=0;
|
||||
HashTable list_destructors, module_registry;
|
||||
|
||||
/* this function doesn't check for too many parameters */
|
||||
int getParameters(HashTable *ht, int param_count,...)
|
||||
{
|
||||
va_list ptr;
|
||||
zval **param, **tmp = NULL, *param_ptr;
|
||||
int i;
|
||||
|
||||
va_start(ptr, param_count);
|
||||
|
||||
for (i = 0; i < param_count; i++) {
|
||||
param = va_arg(ptr, zval **);
|
||||
if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
|
||||
va_end(ptr);
|
||||
return FAILURE;
|
||||
}
|
||||
param_ptr = *tmp;
|
||||
if (!param_ptr->is_ref && param_ptr->refcount>1) {
|
||||
zval *new_tmp;
|
||||
|
||||
new_tmp = (zval *) emalloc(sizeof(zval));
|
||||
*new_tmp = *param_ptr;
|
||||
zval_copy_ctor(new_tmp);
|
||||
new_tmp->refcount = 1;
|
||||
new_tmp->is_ref = 0;
|
||||
param_ptr = new_tmp;
|
||||
zend_hash_index_update(ht, i, ¶m_ptr, sizeof(zval *), NULL);
|
||||
}
|
||||
*param = param_ptr;
|
||||
}
|
||||
va_end(ptr);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int getParametersArray(HashTable *ht, int param_count, zval **argument_array)
|
||||
{
|
||||
int i;
|
||||
zval **tmp = NULL, *param_ptr;
|
||||
|
||||
for (i = 0; i < param_count; i++) {
|
||||
if (zend_hash_index_find(ht, i, (void **) &tmp) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
param_ptr = *tmp;
|
||||
if (!param_ptr->is_ref && param_ptr->refcount>1) {
|
||||
zval *new_tmp;
|
||||
|
||||
new_tmp = (zval *) emalloc(sizeof(zval));
|
||||
*new_tmp = *param_ptr;
|
||||
zval_copy_ctor(new_tmp);
|
||||
new_tmp->refcount = 1;
|
||||
new_tmp->is_ref = 0;
|
||||
param_ptr = new_tmp;
|
||||
zend_hash_index_update(ht, i, ¶m_ptr, sizeof(zval *), NULL);
|
||||
}
|
||||
argument_array[i] = param_ptr;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int getThis(zval **this)
|
||||
{
|
||||
/* NEEDS TO BE IMPLEMENTED FOR ZEND */
|
||||
/*
|
||||
zval *data;
|
||||
|
||||
if (zend_hash_find(GLOBAL(function_state.calling_symbol_table), "this", sizeof("this"), (void **)&data) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*this = data;
|
||||
*/
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int ParameterPassedByReference(HashTable *ht, uint n)
|
||||
{
|
||||
zval **tmp;
|
||||
|
||||
if (zend_hash_index_find(ht, n-1, (void **) &tmp) == FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
return (*tmp)->is_ref;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void wrong_param_count()
|
||||
{
|
||||
zend_error(E_WARNING,"Wrong parameter count for %s()",get_active_function_name());
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int array_init(zval *arg)
|
||||
{
|
||||
arg->value.ht = (HashTable *) emalloc(sizeof(HashTable));
|
||||
if (!arg->value.ht || zend_hash_init(arg->value.ht, 0, NULL, PVAL_PTR_DTOR, 0)) {
|
||||
zend_error(E_CORE_ERROR, "Cannot allocate memory for array");
|
||||
return FAILURE;
|
||||
}
|
||||
arg->type = IS_ARRAY;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void zval_update_const_and_ref(zval **p)
|
||||
{
|
||||
zval_update_constant(*p);
|
||||
zval_add_ref(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZEND_API inline int object_init_ex(zval *arg, zend_class_entry *class_type)
|
||||
{
|
||||
zval *tmp;
|
||||
|
||||
arg->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable));
|
||||
zend_hash_init(arg->value.obj.properties, 0, NULL, PVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(arg->value.obj.properties, &class_type->default_properties, (void (*)(void *)) zval_update_const_and_ref, (void *) &tmp, sizeof(zval *));
|
||||
arg->type = IS_OBJECT;
|
||||
arg->value.obj.ce = class_type;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int object_init(zval *arg)
|
||||
{
|
||||
return object_init_ex(arg, &standard_class);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_assoc_long(zval *arg, char *key, long n)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_LONG;
|
||||
tmp->value.lval = n;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_assoc_double(zval *arg, char *key, double d)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_DOUBLE;
|
||||
tmp->value.dval = d;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_assoc_string(zval *arg, char *key, char *str, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_assoc_stringl(zval *arg, char *key, char *str, uint length, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_assoc_function(zval *arg, char *key,void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS))
|
||||
{
|
||||
zend_error(E_WARNING, "add_assoc_function() is no longer supported");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_index_long(zval *arg, uint index, long n)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_LONG;
|
||||
tmp->value.lval = n;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_index_double(zval *arg, uint index, double d)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_DOUBLE;
|
||||
tmp->value.dval = d;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_index_string(zval *arg, uint index, char *str, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_index_stringl(zval *arg, uint index, char *str, uint length, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_next_index_long(zval *arg, long n)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_LONG;
|
||||
tmp->value.lval = n;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_next_index_double(zval *arg, double d)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_DOUBLE;
|
||||
tmp->value.dval = d;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_next_index_string(zval *arg, char *str, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *),NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_assoc_string(zval *arg, char *key, char *str, void **dest, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length, void **dest, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_index_long(zval *arg, uint index, long l, void **dest)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_LONG;
|
||||
tmp->value.lval= l;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_index_double(zval *arg, uint index, double d, void **dest)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_DOUBLE;
|
||||
tmp->value.dval= d;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_index_string(zval *arg, uint index, char *str, void **dest, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_get_index_stringl(zval *arg, uint index, char *str, uint length, void **dest, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *),dest);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_property_long(zval *arg, char *key, long n)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_LONG;
|
||||
tmp->value.lval = n;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_property_double(zval *arg, char *key, double d)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_DOUBLE;
|
||||
tmp->value.dval = d;
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_property_string(zval *arg, char *key, char *str, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = strlen(str);
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int add_property_stringl(zval *arg, char *key, char *str, uint length, int duplicate)
|
||||
{
|
||||
zval *tmp = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
tmp->type = IS_STRING;
|
||||
tmp->value.str.len = length;
|
||||
if (duplicate) {
|
||||
tmp->value.str.val = estrndup(str,tmp->value.str.len);
|
||||
} else {
|
||||
tmp->value.str.val = str;
|
||||
}
|
||||
tmp->refcount=1;
|
||||
tmp->is_ref=0;
|
||||
return zend_hash_update(arg->value.obj.properties, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
|
||||
int zend_startup_module(zend_module_entry *module)
|
||||
{
|
||||
if (module) {
|
||||
module->module_number = zend_next_free_module();
|
||||
if (module->module_startup_func) {
|
||||
if (module->module_startup_func(MODULE_PERSISTENT, module->module_number)==FAILURE) {
|
||||
zend_error(E_CORE_ERROR,"Unable to start %s module",module->name);
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
module->type = MODULE_PERSISTENT;
|
||||
register_module(module);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int _register_list_destructors(void (*list_destructor)(void *), void (*plist_destructor)(void *), int module_number)
|
||||
{
|
||||
list_destructors_entry ld;
|
||||
|
||||
#if 0
|
||||
printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
|
||||
#endif
|
||||
|
||||
ld.list_destructor=(void (*)(void *)) list_destructor;
|
||||
ld.plist_destructor=(void (*)(void *)) plist_destructor;
|
||||
ld.module_number = module_number;
|
||||
ld.resource_id = list_destructors.nNextFreeElement;
|
||||
|
||||
if (zend_hash_next_index_insert(&list_destructors,(void *) &ld,sizeof(list_destructors_entry),NULL)==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
return list_destructors.nNextFreeElement-1;
|
||||
}
|
||||
|
||||
|
||||
/* registers all functions in *library_functions in the function hash */
|
||||
int register_functions(function_entry *functions)
|
||||
{
|
||||
function_entry *ptr = functions;
|
||||
zend_internal_function internal_function;
|
||||
int count=0,unload=0;
|
||||
CLS_FETCH();
|
||||
|
||||
internal_function.type = ZEND_INTERNAL_FUNCTION;
|
||||
|
||||
while (ptr->fname) {
|
||||
internal_function.handler = ptr->handler;
|
||||
internal_function.arg_types = ptr->func_arg_types;
|
||||
internal_function.function_name = ptr->fname;
|
||||
if (!internal_function.handler) {
|
||||
zend_error(E_CORE_WARNING,"Null function defined as active function");
|
||||
unregister_functions(functions,count);
|
||||
return FAILURE;
|
||||
}
|
||||
if (zend_hash_add(CG(function_table), ptr->fname, strlen(ptr->fname)+1, &internal_function, sizeof(zend_internal_function), NULL) == FAILURE) {
|
||||
unload=1;
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
count++;
|
||||
}
|
||||
if (unload) { /* before unloading, display all remaining bad function in the module */
|
||||
while (ptr->fname) {
|
||||
if (zend_hash_exists(CG(function_table), ptr->fname, strlen(ptr->fname)+1)) {
|
||||
zend_error(E_CORE_WARNING,"Module load failed - duplicate function name - %s",ptr->fname);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
unregister_functions(functions,count);
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* count=-1 means erase all functions, otherwise,
|
||||
* erase the first count functions
|
||||
*/
|
||||
void unregister_functions(function_entry *functions,int count)
|
||||
{
|
||||
function_entry *ptr = functions;
|
||||
int i=0;
|
||||
CLS_FETCH();
|
||||
|
||||
while (ptr->fname) {
|
||||
if (count!=-1 && i>=count) {
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
zend_printf("Unregistering %s()\n",ptr->fname);
|
||||
#endif
|
||||
zend_hash_del(CG(function_table),ptr->fname,strlen(ptr->fname)+1);
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int register_module(zend_module_entry *module)
|
||||
{
|
||||
#if 0
|
||||
zend_printf("%s: Registering module %d\n",module->name, module->module_number);
|
||||
#endif
|
||||
if (register_functions(module->functions)==FAILURE) {
|
||||
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load",module->name);
|
||||
return FAILURE;
|
||||
}
|
||||
module->module_started=1;
|
||||
return zend_hash_add(&module_registry, module->name,strlen(module->name)+1,(void *)module,sizeof(zend_module_entry),NULL);
|
||||
}
|
||||
|
||||
|
||||
void module_destructor(zend_module_entry *module)
|
||||
{
|
||||
if (module->type == MODULE_TEMPORARY) {
|
||||
zend_hash_apply_with_argument(&list_destructors, (int (*)(void *,void *)) clean_module_resource_destructors, (void *) &(module->module_number));
|
||||
clean_module_constants(module->module_number);
|
||||
}
|
||||
|
||||
if (module->request_started && module->request_shutdown_func) {
|
||||
#if 0
|
||||
zend_printf("%s: Request shutdown\n",module->name);
|
||||
#endif
|
||||
module->request_shutdown_func();
|
||||
}
|
||||
module->request_started=0;
|
||||
if (module->module_started && module->module_shutdown_func) {
|
||||
#if 0
|
||||
zend_printf("%s: Module shutdown\n",module->name);
|
||||
#endif
|
||||
module->module_shutdown_func();
|
||||
}
|
||||
module->module_started=0;
|
||||
unregister_functions(module->functions,-1);
|
||||
|
||||
#if HAVE_LIBDL
|
||||
if (module->handle) {
|
||||
dlclose(module->handle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* call request startup for all modules */
|
||||
int module_registry_request_startup(zend_module_entry *module)
|
||||
{
|
||||
if (!module->request_started && module->request_startup_func) {
|
||||
#if 0
|
||||
zend_printf("%s: Request startup\n",module->name);
|
||||
#endif
|
||||
module->request_startup_func(module->type, module->module_number);
|
||||
}
|
||||
module->request_started=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* for persistent modules - call request shutdown and flag NOT to erase
|
||||
* for temporary modules - do nothing, and flag to erase
|
||||
*/
|
||||
int module_registry_cleanup(zend_module_entry *module)
|
||||
{
|
||||
switch(module->type) {
|
||||
case MODULE_PERSISTENT:
|
||||
if (module->request_started && module->request_shutdown_func) {
|
||||
#if 0
|
||||
zend_printf("%s: Request shutdown\n",module->name);
|
||||
#endif
|
||||
module->request_shutdown_func();
|
||||
}
|
||||
module->request_started=0;
|
||||
return 0;
|
||||
break;
|
||||
case MODULE_TEMPORARY:
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* return the next free module number */
|
||||
int zend_next_free_module(void)
|
||||
{
|
||||
return ++module_count;
|
||||
}
|
||||
|
||||
|
||||
zend_class_entry *register_internal_class(zend_class_entry *class_entry)
|
||||
{
|
||||
zend_class_entry *register_class;
|
||||
char *lowercase_name = zend_strndup(class_entry->name, class_entry->name_length);
|
||||
CLS_FETCH();
|
||||
|
||||
zend_str_tolower(lowercase_name, class_entry->name_length);
|
||||
|
||||
class_entry->type = ZEND_INTERNAL_CLASS;
|
||||
class_entry->parent = NULL;
|
||||
zend_hash_init(&class_entry->default_properties, 0, NULL, PVAL_PTR_DTOR, 1);
|
||||
zend_hash_init(&class_entry->function_table, 0, NULL, (void (*)(void *)) destroy_zend_function, 1);
|
||||
|
||||
zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, class_entry, sizeof(zend_class_entry), (void **) ®ister_class);
|
||||
free(lowercase_name);
|
||||
return register_class;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_API_H
|
||||
#define _ZEND_API_H
|
||||
|
||||
#include "modules.h"
|
||||
#include "zend_list.h"
|
||||
|
||||
|
||||
int zend_next_free_module(void);
|
||||
|
||||
int getParameters(HashTable *ht, int param_count,...);
|
||||
int getParametersArray(HashTable *ht, int param_count, zval **argument_array);
|
||||
int getThis(zval **this);
|
||||
int ParameterPassedByReference(HashTable *ht, uint n);
|
||||
int register_functions(function_entry *functions);
|
||||
void unregister_functions(function_entry *functions, int count);
|
||||
int register_module(zend_module_entry *module_entry);
|
||||
zend_class_entry *register_internal_class(zend_class_entry *class_entry);
|
||||
|
||||
ZEND_API void wrong_param_count(void);
|
||||
|
||||
#define WRONG_PARAM_COUNT { wrong_param_count(); return; }
|
||||
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) { wrong_param_count(); return ret; }
|
||||
#define ARG_COUNT(ht) (ht->nNextFreeElement)
|
||||
|
||||
#define BYREF_NONE 0
|
||||
#define BYREF_FORCE 1
|
||||
#define BYREF_ALLOW 2
|
||||
|
||||
#if !MSVC5
|
||||
#define DLEXPORT
|
||||
#endif
|
||||
|
||||
int zend_startup_module(zend_module_entry *module);
|
||||
|
||||
ZEND_API int array_init(zval *arg);
|
||||
ZEND_API int object_init(zval *arg);
|
||||
ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
|
||||
ZEND_API int add_assoc_long(zval *arg, char *key, long n);
|
||||
ZEND_API int add_assoc_double(zval *arg, char *key, double d);
|
||||
ZEND_API int add_assoc_string(zval *arg, char *key, char *str, int duplicate);
|
||||
ZEND_API int add_assoc_stringl(zval *arg, char *key, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_assoc_function(zval *arg, char *key,void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));
|
||||
ZEND_API int add_index_long(zval *arg, uint idx, long n);
|
||||
ZEND_API int add_index_double(zval *arg, uint idx, double d);
|
||||
ZEND_API int add_index_string(zval *arg, uint idx, char *str, int duplicate);
|
||||
ZEND_API int add_index_stringl(zval *arg, uint idx, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_next_index_long(zval *arg, long n);
|
||||
ZEND_API int add_next_index_double(zval *arg, double d);
|
||||
ZEND_API int add_next_index_string(zval *arg, char *str, int duplicate);
|
||||
ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate);
|
||||
|
||||
ZEND_API int add_get_assoc_string(zval *arg, char *key, char *str, void **dest, int duplicate);
|
||||
ZEND_API int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_long(zval *arg, uint idx, long l, void **dest);
|
||||
ZEND_API int add_get_index_double(zval *arg, uint idx, double d, void **dest);
|
||||
ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
|
||||
|
||||
ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[]);
|
||||
|
||||
|
||||
ZEND_API int add_property_long(zval *arg, char *key, long l);
|
||||
ZEND_API int add_property_double(zval *arg, char *key, double d);
|
||||
ZEND_API int add_property_string(zval *arg, char *key, char *str, int duplicate);
|
||||
ZEND_API int add_property_stringl(zval *arg, char *key, char *str, uint length, int duplicate);
|
||||
|
||||
#define add_method(arg,key,method) add_assoc_function((arg),(key),(method))
|
||||
|
||||
#endif /* _ZEND_API_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_alloc.h"
|
||||
#include "zend_globals.h"
|
||||
|
||||
#ifndef ZTS
|
||||
static zend_alloc_globals alloc_globals;
|
||||
#endif
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
# define END_MAGIC_SIZE sizeof(long)
|
||||
# define END_ALIGNMENT(size) (((size)%PLATFORM_ALIGNMENT)?(PLATFORM_ALIGNMENT-((size)%PLATFORM_ALIGNMENT)):0)
|
||||
#else
|
||||
# define END_MAGIC_SIZE 0
|
||||
# define END_ALIGNMENT(size) 0
|
||||
#endif
|
||||
|
||||
|
||||
# if MEMORY_LIMIT
|
||||
# if ZEND_DEBUG
|
||||
#define CHECK_MEMORY_LIMIT(s) _CHECK_MEMORY_LIMIT(s,filename,lineno)
|
||||
# else
|
||||
#define CHECK_MEMORY_LIMIT(s) _CHECK_MEMORY_LIMIT(s,NULL,0)
|
||||
# endif
|
||||
|
||||
#define _CHECK_MEMORY_LIMIT(s,file,lineno) { AG(allocated_memory) += (s);\
|
||||
if (php3_ini.memory_limit<AG(allocated_memory)) {\
|
||||
if (!file) { \
|
||||
zend_error(E_ERROR,"Allowed memory size of %d bytes exhausted (tried to allocate %d bytes)",php3_ini.memory_limit,s); \
|
||||
} else { \
|
||||
zend_error(E_ERROR,"Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes)",php3_ini.memory_limit,file,lineno,s); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
# endif
|
||||
|
||||
#ifndef CHECK_MEMORY_LIMIT
|
||||
#define CHECK_MEMORY_LIMIT(s)
|
||||
#endif
|
||||
|
||||
|
||||
#define REMOVE_POINTER_FROM_LIST(p) \
|
||||
if (!p->persistent && p==AG(head)) { \
|
||||
AG(head) = p->pNext; \
|
||||
} else if (p->persistent && p==AG(phead)) { \
|
||||
AG(phead) = p->pNext; \
|
||||
} else { \
|
||||
p->pLast->pNext = p->pNext; \
|
||||
} \
|
||||
if (p->pNext) { \
|
||||
p->pNext->pLast = p->pLast; \
|
||||
}
|
||||
|
||||
#define ADD_POINTER_TO_LIST(p) \
|
||||
if (p->persistent) { \
|
||||
p->pNext = AG(phead); \
|
||||
if (AG(phead)) { \
|
||||
AG(phead)->pLast = p; \
|
||||
} \
|
||||
AG(phead) = p; \
|
||||
} else { \
|
||||
p->pNext = AG(head); \
|
||||
if (AG(head)) { \
|
||||
AG(head)->pLast = p; \
|
||||
} \
|
||||
AG(head) = p; \
|
||||
} \
|
||||
p->pLast = (mem_header *) NULL;
|
||||
|
||||
|
||||
/* used by ISAPI and NSAPI */
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void *_emalloc(size_t size, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API void *_emalloc(size_t size)
|
||||
#endif
|
||||
{
|
||||
mem_header *p;
|
||||
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
|
||||
if ((size < MAX_CACHED_MEMORY) && (AG(cache_count)[size] > 0)) {
|
||||
p = AG(cache)[size][--AG(cache_count)[size]];
|
||||
#if ZEND_DEBUG
|
||||
p->filename = filename;
|
||||
p->lineno = lineno;
|
||||
p->magic = MEM_BLOCK_START_MAGIC;
|
||||
#endif
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
p->persistent = 0;
|
||||
p->cached = 0;
|
||||
return (void *)((char *)p + sizeof(mem_header) + PLATFORM_PADDING);
|
||||
} else {
|
||||
p = (mem_header *) malloc(sizeof(mem_header) + size + PLATFORM_PADDING + END_ALIGNMENT(size) + END_MAGIC_SIZE);
|
||||
}
|
||||
|
||||
if (!p) {
|
||||
fprintf(stderr,"FATAL: emalloc(): Unable to allocate %d bytes\n", size);
|
||||
exit(1);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (void *)p;
|
||||
}
|
||||
p->persistent = p->cached = 0;
|
||||
ADD_POINTER_TO_LIST(p);
|
||||
p->size = size;
|
||||
#if ZEND_DEBUG
|
||||
p->filename = filename;
|
||||
p->lineno = lineno;
|
||||
p->magic = MEM_BLOCK_START_MAGIC;
|
||||
*((long *)(((char *) p) + sizeof(mem_header)+size+PLATFORM_PADDING+END_ALIGNMENT(size))) = MEM_BLOCK_END_MAGIC;
|
||||
#endif
|
||||
#if MEMORY_LIMIT
|
||||
CHECK_MEMORY_LIMIT(size);
|
||||
#endif
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (void *)((char *)p + sizeof(mem_header) + PLATFORM_PADDING);
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void _efree(void *ptr, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API void _efree(void *ptr)
|
||||
#endif
|
||||
{
|
||||
mem_header *p = (mem_header *) ((char *)ptr - sizeof(mem_header) - PLATFORM_PADDING);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
_mem_block_check(ptr, 1, filename, lineno);
|
||||
memset(ptr, 0x5a, p->size);
|
||||
#endif
|
||||
|
||||
if (!p->persistent && (p->size < MAX_CACHED_MEMORY) && (AG(cache_count)[p->size] < MAX_CACHED_ENTRIES)) {
|
||||
AG(cache)[p->size][AG(cache_count)[p->size]++] = p;
|
||||
p->cached = 1;
|
||||
#if ZEND_DEBUG
|
||||
p->magic = MEM_BLOCK_CACHED_MAGIC;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
REMOVE_POINTER_FROM_LIST(p);
|
||||
|
||||
#if MEMORY_LIMIT
|
||||
AG(allocated_memory) -= p->size;
|
||||
#endif
|
||||
|
||||
free(p);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void *_ecalloc(size_t nmemb, size_t size, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API void *_ecalloc(size_t nmemb, size_t size)
|
||||
#endif
|
||||
{
|
||||
void *p;
|
||||
int final_size=size*nmemb;
|
||||
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
#if ZEND_DEBUG
|
||||
p = _emalloc(final_size,filename,lineno);
|
||||
#else
|
||||
p = emalloc(final_size);
|
||||
#endif
|
||||
if (!p) {
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (void *) p;
|
||||
}
|
||||
memset(p,(int)NULL,final_size);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void *_erealloc(void *ptr, size_t size, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API void *_erealloc(void *ptr, size_t size)
|
||||
#endif
|
||||
{
|
||||
mem_header *p = (mem_header *) ((char *)ptr-sizeof(mem_header)-PLATFORM_PADDING);
|
||||
mem_header *orig = p;
|
||||
|
||||
if (!ptr) {
|
||||
#if ZEND_DEBUG
|
||||
return _emalloc(size, filename, lineno);
|
||||
#else
|
||||
return emalloc(size);
|
||||
#endif
|
||||
}
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
REMOVE_POINTER_FROM_LIST(p);
|
||||
p = (mem_header *) realloc(p,sizeof(mem_header)+size+PLATFORM_PADDING+END_ALIGNMENT(size)+END_MAGIC_SIZE);
|
||||
if (!p) {
|
||||
fprintf(stderr,"FATAL: erealloc(): Unable to allocate %d bytes\n", size);
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
zend_bailout();
|
||||
ADD_POINTER_TO_LIST(orig);
|
||||
return (void *)NULL;
|
||||
}
|
||||
ADD_POINTER_TO_LIST(p);
|
||||
#if ZEND_DEBUG
|
||||
p->filename = filename;
|
||||
p->lineno = lineno;
|
||||
p->magic = MEM_BLOCK_START_MAGIC;
|
||||
*((long *)(((char *) p) + sizeof(mem_header)+size+PLATFORM_PADDING+END_ALIGNMENT(size))) = MEM_BLOCK_END_MAGIC;
|
||||
#endif
|
||||
#if MEMORY_LIMIT
|
||||
CHECK_MEMORY_LIMIT(size - p->size);
|
||||
#endif
|
||||
p->size = size;
|
||||
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (void *)((char *)p+sizeof(mem_header)+PLATFORM_PADDING);
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API char *_estrdup(const char *s, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API char *_estrdup(const char *s)
|
||||
#endif
|
||||
{
|
||||
int length;
|
||||
char *p;
|
||||
|
||||
length = strlen(s)+1;
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
#if ZEND_DEBUG
|
||||
p = (char *) _emalloc(length,filename,lineno);
|
||||
#else
|
||||
p = (char *) emalloc(length);
|
||||
#endif
|
||||
if (!p) {
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (char *)NULL;
|
||||
}
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
memcpy(p,s,length);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API char *_estrndup(const char *s, uint length, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API char *_estrndup(const char *s, uint length)
|
||||
#endif
|
||||
{
|
||||
char *p;
|
||||
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
#if ZEND_DEBUG
|
||||
p = (char *) _emalloc(length+1,filename,lineno);
|
||||
#else
|
||||
p = (char *) emalloc(length+1);
|
||||
#endif
|
||||
if (!p) {
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (char *)NULL;
|
||||
}
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
memcpy(p,s,length);
|
||||
p[length]=0;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, uint length)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = (char *) malloc(length+1);
|
||||
if (!p) {
|
||||
return (char *)NULL;
|
||||
}
|
||||
if (length) {
|
||||
memcpy(p,s,length);
|
||||
}
|
||||
p[length]=0;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void start_memory_manager(void)
|
||||
{
|
||||
AG(phead) = AG(head) = NULL;
|
||||
|
||||
#if MEMORY_LIMIT
|
||||
AG(allocated_memory)=0;
|
||||
AG(memory_exhausted)=0;
|
||||
#endif
|
||||
|
||||
memset(AG(cache_count),0,MAX_CACHED_MEMORY*sizeof(unsigned char));
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void shutdown_memory_manager(int silent, int clean_cache)
|
||||
{
|
||||
mem_header *p, *t;
|
||||
|
||||
p=AG(head);
|
||||
t=AG(head);
|
||||
while (t) {
|
||||
if (!t->cached || clean_cache) {
|
||||
#if ZEND_DEBUG
|
||||
if (!t->cached) {
|
||||
/* does not use zend_error() *intentionally* */
|
||||
if (!silent) {
|
||||
zend_message_dispatcher(ZMSG_MEMORY_LEAK_DETECTED, t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
p = t->pNext;
|
||||
REMOVE_POINTER_FROM_LIST(t);
|
||||
free(t);
|
||||
t = p;
|
||||
} else {
|
||||
t = t->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API int _mem_block_check(void *ptr, int silent, char *filename, int lineno)
|
||||
{
|
||||
mem_header *p = (mem_header *) ((char *)ptr - sizeof(mem_header) - PLATFORM_PADDING);
|
||||
int no_cache_notice=0;
|
||||
int valid_beginning=1;
|
||||
int had_problems=0;
|
||||
|
||||
if (silent==2) {
|
||||
silent=1;
|
||||
no_cache_notice=1;
|
||||
}
|
||||
if (silent==3) {
|
||||
silent=0;
|
||||
no_cache_notice=1;
|
||||
}
|
||||
if (!silent) {
|
||||
fprintf(stderr,"---------------------------------------\n");
|
||||
fprintf(stderr,"Block 0x%0.8lX status at %s:%d:\n", (long) p, filename, lineno);
|
||||
fprintf(stderr,"%10s\t","Beginning: ");
|
||||
}
|
||||
|
||||
switch (p->magic) {
|
||||
case MEM_BLOCK_START_MAGIC:
|
||||
if (!silent) {
|
||||
fprintf(stderr, "OK (allocated on %s:%d, %d bytes)\n", p->filename, p->lineno, p->size);
|
||||
}
|
||||
break; /* ok */
|
||||
case MEM_BLOCK_FREED_MAGIC:
|
||||
if (!silent) {
|
||||
fprintf(stderr,"Freed\n");
|
||||
had_problems=1;
|
||||
} else {
|
||||
return _mem_block_check(ptr, 0, filename, lineno);
|
||||
}
|
||||
break;
|
||||
case MEM_BLOCK_CACHED_MAGIC:
|
||||
if (!silent) {
|
||||
if (!no_cache_notice) {
|
||||
fprintf(stderr,"Cached (allocated on %s:%d, %d bytes)\n", p->filename, p->lineno, p->size);
|
||||
had_problems=1;
|
||||
}
|
||||
} else {
|
||||
if (!no_cache_notice) {
|
||||
return _mem_block_check(ptr, 0, filename, lineno);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!silent) {
|
||||
fprintf(stderr,"Overrun (magic=0x%0.8lX, expected=0x%0.8lX)\n", p->magic, MEM_BLOCK_START_MAGIC);
|
||||
} else {
|
||||
return _mem_block_check(ptr, 0, filename, lineno);
|
||||
}
|
||||
had_problems=1;
|
||||
valid_beginning=0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (valid_beginning
|
||||
&& *((long *)(((char *) p)+sizeof(mem_header)+p->size+PLATFORM_PADDING+END_ALIGNMENT(p->size))) != MEM_BLOCK_END_MAGIC) {
|
||||
long magic_num = MEM_BLOCK_END_MAGIC;
|
||||
char *overflow_ptr, *magic_ptr=(char *) &magic_num;
|
||||
int overflows=0;
|
||||
int i;
|
||||
|
||||
if (silent) {
|
||||
return _mem_block_check(ptr, 0, filename, lineno);
|
||||
}
|
||||
had_problems=1;
|
||||
overflow_ptr = ((char *) p)+sizeof(mem_header)+p->size+PLATFORM_PADDING;
|
||||
|
||||
for (i=0; i<sizeof(long); i++) {
|
||||
if (overflow_ptr[i]!=magic_ptr[i]) {
|
||||
overflows++;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,"%10s\t", "End:");
|
||||
fprintf(stderr,"Overflown (magic=0x%0.8lX instead of 0x%0.8lX)\n",
|
||||
*((long *)(((char *) p) + sizeof(mem_header)+p->size+PLATFORM_PADDING+END_ALIGNMENT(p->size))), MEM_BLOCK_END_MAGIC);
|
||||
fprintf(stderr,"%10s\t","");
|
||||
if (overflows>=sizeof(long)) {
|
||||
fprintf(stderr, "At least %d bytes overflown\n", sizeof(long));
|
||||
} else {
|
||||
fprintf(stderr, "%d byte(s) overflown\n", overflows);
|
||||
}
|
||||
} else if (!silent) {
|
||||
fprintf(stderr,"%10s\t", "End:");
|
||||
if (valid_beginning) {
|
||||
fprintf(stderr,"OK\n");
|
||||
} else {
|
||||
fprintf(stderr,"Unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
fprintf(stderr,"---------------------------------------\n");
|
||||
}
|
||||
return ((!had_problems) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void _full_mem_check(int silent, char *filename, uint lineno)
|
||||
{
|
||||
mem_header *p = AG(head);
|
||||
int errors=0;
|
||||
|
||||
fprintf(stderr,"------------------------------------------------\n");
|
||||
fprintf(stderr,"Full Memory Check at %s:%d\n", filename, lineno);
|
||||
|
||||
while (p) {
|
||||
if (!_mem_block_check((void *)((char *)p + sizeof(mem_header) + PLATFORM_PADDING), (silent?2:3), filename, lineno)) {
|
||||
errors++;
|
||||
}
|
||||
p = p->pNext;
|
||||
}
|
||||
fprintf(stderr,"End of full memory check %s:%d (%d errors)\n", filename, lineno, errors);
|
||||
fprintf(stderr,"------------------------------------------------\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void _persist_alloc(void *ptr, char *filename, uint lineno)
|
||||
#else
|
||||
ZEND_API void _persist_alloc(void *ptr)
|
||||
#endif
|
||||
{
|
||||
mem_header *p = (mem_header *) ((char *)ptr-sizeof(mem_header)-PLATFORM_PADDING);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
_mem_block_check(ptr, 1, filename, lineno);
|
||||
#endif
|
||||
|
||||
/* remove the block from the non persistent list */
|
||||
REMOVE_POINTER_FROM_LIST(p);
|
||||
|
||||
p->persistent = 1;
|
||||
|
||||
/* add the block to the persistent list */
|
||||
ADD_POINTER_TO_LIST(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ALLOC_H
|
||||
#define _ALLOC_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MEM_BLOCK_START_MAGIC 0x7312F8DCL
|
||||
#define MEM_BLOCK_END_MAGIC 0x2A8FCC84L
|
||||
#define MEM_BLOCK_FREED_MAGIC 0x99954317L
|
||||
#define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
|
||||
|
||||
typedef struct _mem_header {
|
||||
#if ZEND_DEBUG
|
||||
long magic;
|
||||
char *filename;
|
||||
uint lineno;
|
||||
#endif
|
||||
struct _mem_header *pNext;
|
||||
struct _mem_header *pLast;
|
||||
unsigned int size:30;
|
||||
unsigned int persistent:1;
|
||||
unsigned int cached:1;
|
||||
} mem_header;
|
||||
|
||||
typedef union {
|
||||
void *ptr;
|
||||
double dbl;
|
||||
long lng;
|
||||
} align_test;
|
||||
|
||||
#define MAX_CACHED_MEMORY 64
|
||||
#define MAX_CACHED_ENTRIES 16
|
||||
|
||||
#define PLATFORM_ALIGNMENT (sizeof(align_test))
|
||||
#define PLATFORM_PADDING (((PLATFORM_ALIGNMENT-sizeof(mem_header))%PLATFORM_ALIGNMENT+PLATFORM_ALIGNMENT)%PLATFORM_ALIGNMENT)
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, unsigned int length);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API void *_emalloc(size_t size,char *filename,uint lineno);
|
||||
ZEND_API void _efree(void *ptr,char *filename,uint lineno);
|
||||
ZEND_API void *_ecalloc(size_t nmemb, size_t size,char *filename,uint lineno);
|
||||
ZEND_API void *_erealloc(void *ptr, size_t size,char *filename,uint lineno);
|
||||
ZEND_API char *_estrdup(const char *s,char *filename,uint lineno);
|
||||
ZEND_API char *_estrndup(const char *s, unsigned int length,char *filename,uint lineno);
|
||||
ZEND_API void _persist_alloc(void *ptr, char *filename, uint lineno);
|
||||
#define emalloc(size) _emalloc((size),__FILE__,__LINE__)
|
||||
#define efree(ptr) _efree((ptr),__FILE__,__LINE__)
|
||||
#define ecalloc(nmemb,size) _ecalloc((nmemb),(size),__FILE__,__LINE__)
|
||||
#define erealloc(ptr,size) _erealloc((ptr),(size),__FILE__,__LINE__)
|
||||
#define estrdup(s) _estrdup((s),__FILE__,__LINE__)
|
||||
#define estrndup(s,length) _estrndup((s),(length),__FILE__,__LINE__)
|
||||
#define persist_alloc(p) _persist_alloc((p),__FILE__,__LINE__)
|
||||
#else
|
||||
ZEND_API void *_emalloc(size_t size);
|
||||
ZEND_API void _efree(void *ptr);
|
||||
ZEND_API void *_ecalloc(size_t nmemb, size_t size);
|
||||
ZEND_API void *_erealloc(void *ptr, size_t size);
|
||||
ZEND_API char *_estrdup(const char *s);
|
||||
ZEND_API char *_estrndup(const char *s, unsigned int length);
|
||||
ZEND_API void _persist_alloc(void *ptr);
|
||||
#define emalloc(size) _emalloc((size))
|
||||
#define efree(ptr) _efree((ptr))
|
||||
#define ecalloc(nmemb,size) _ecalloc((nmemb),(size))
|
||||
#define erealloc(ptr,size) _erealloc((ptr),(size))
|
||||
#define estrdup(s) _estrdup((s))
|
||||
#define estrndup(s,length) _estrndup((s),(length))
|
||||
#define persist_alloc(p) _persist_alloc((p))
|
||||
#endif
|
||||
|
||||
#define pemalloc(size,persistent) ((persistent)?malloc(size):emalloc(size))
|
||||
#define pefree(ptr,persistent) ((persistent)?free(ptr):efree(ptr))
|
||||
#define pecalloc(nmemb,size,persistent) ((persistent)?calloc((nmemb),(size)):ecalloc((nmemb),(size)))
|
||||
#define perealloc(ptr,size,persistent) ((persistent)?realloc((ptr),(size)):erealloc((ptr),(size)))
|
||||
#define pestrdup(s,persistent) ((persistent)?strdup(s):estrdup(s))
|
||||
|
||||
#define safe_estrdup(ptr) ((ptr)?(estrdup(ptr)):(empty_string))
|
||||
#define safe_estrndup(ptr,len) ((ptr)?(estrndup((ptr),(len))):(empty_string))
|
||||
|
||||
ZEND_API void start_memory_manager(void);
|
||||
ZEND_API void shutdown_memory_manager(int silent, int clean_cache);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_API int _mem_block_check(void *ptr, int silent, char *filename, int lineno);
|
||||
ZEND_API void _full_mem_check(int silent, char *filename, uint lineno);
|
||||
#define mem_block_check(ptr, silent) _mem_block_check(ptr, silent, __FILE__, __LINE__)
|
||||
#define mem_block_check(ptr, silent) _mem_block_check(ptr, silent, __FILE__, __LINE__)
|
||||
#define full_mem_check(silent) _full_mem_check(silent, __FILE__, __LINE__)
|
||||
#else
|
||||
#define mem_block_check(type, ptr, silent)
|
||||
#define full_mem_check(silent)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
+1822
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _COMPILE_H
|
||||
#define _COMPILE_H
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_llist.h"
|
||||
#define YYSTYPE znode
|
||||
#include "zend-parser.h"
|
||||
|
||||
#define DEBUG_ZEND 0
|
||||
#define SUPPORT_INTERACTIVE 1
|
||||
|
||||
#define FREE_PNODE(znode) zval_dtor(&znode->u.constant);
|
||||
#define FREE_OP(op, should_free) if (should_free) zval_dtor(&Ts[(op)->u.var].tmp_var);
|
||||
|
||||
|
||||
#if SUPPORT_INTERACTIVE
|
||||
#define INC_BPC(op_array) ((op_array)->backpatch_count++)
|
||||
#define DEC_BPC(op_array) ((op_array)->backpatch_count--)
|
||||
#define HANDLE_INTERACTIVE() if (EG(interactive)) { execute_new_code(CLS_C); }
|
||||
#else
|
||||
#define INC_BPC(op_array)
|
||||
#define DEC_BPC(op_array)
|
||||
#define HANDLE_INTERACTIVE()
|
||||
#endif
|
||||
|
||||
typedef struct _zend_op_array zend_op_array;
|
||||
|
||||
typedef struct {
|
||||
int op_type;
|
||||
union {
|
||||
zval constant;
|
||||
|
||||
int var;
|
||||
int opline_num;
|
||||
zend_op_array *op_array;
|
||||
struct {
|
||||
int var; /* dummy */
|
||||
int type;
|
||||
} EA;
|
||||
} u;
|
||||
} znode;
|
||||
|
||||
|
||||
typedef struct _zend_op {
|
||||
int opcode;
|
||||
znode result;
|
||||
znode op1;
|
||||
znode op2;
|
||||
char *filename;
|
||||
uint lineno;
|
||||
} zend_op;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int cont;
|
||||
int brk;
|
||||
int parent;
|
||||
} zend_brk_cont_element;
|
||||
|
||||
|
||||
struct _zend_op_array {
|
||||
int type; /* MUST be the first element of this struct! */
|
||||
|
||||
unsigned char *arg_types; /* MUST be the second element of this struct! */
|
||||
|
||||
int *refcount;
|
||||
|
||||
zend_op *opcodes;
|
||||
int last, size;
|
||||
|
||||
int T;
|
||||
|
||||
char *function_name;
|
||||
|
||||
zend_brk_cont_element *brk_cont_array;
|
||||
int last_brk_cont;
|
||||
int current_brk_cont;
|
||||
|
||||
/* static variables support */
|
||||
HashTable *static_variables;
|
||||
|
||||
#if SUPPORT_INTERACTIVE
|
||||
int start_op_number, end_op_number;
|
||||
int last_executed_op_number;
|
||||
int backpatch_count;
|
||||
#endif
|
||||
|
||||
void *reserved[4];
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type; /* MUST be the first element of this struct! */
|
||||
|
||||
unsigned char *arg_types; /* MUST be the second element of this struct */
|
||||
|
||||
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
|
||||
char *function_name;
|
||||
} zend_internal_function;
|
||||
|
||||
|
||||
typedef union {
|
||||
int type; /* MUST be the first element of this struct! */
|
||||
struct {
|
||||
int type; /* never used */
|
||||
unsigned char *arg_types;
|
||||
} common;
|
||||
|
||||
zend_op_array op_array;
|
||||
zend_internal_function internal_function;
|
||||
} zend_function;
|
||||
|
||||
|
||||
typedef struct {
|
||||
HashTable *function_symbol_table;
|
||||
zend_function *function;
|
||||
void *reserved[4];
|
||||
} zend_function_state;
|
||||
|
||||
|
||||
typedef struct {
|
||||
znode cond;
|
||||
int default_case;
|
||||
int control_var;
|
||||
} zend_switch_entry;
|
||||
|
||||
|
||||
typedef struct {
|
||||
znode var;
|
||||
zend_llist dimensions;
|
||||
znode value;
|
||||
} list_llist_element;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
char *filename;
|
||||
union {
|
||||
int fd;
|
||||
FILE *fp;
|
||||
#ifdef __cplusplus
|
||||
istream *is;
|
||||
#endif
|
||||
} handle;
|
||||
} zend_file_handle;
|
||||
|
||||
|
||||
#include "zend_globals.h"
|
||||
|
||||
#define IS_CONST (1<<0)
|
||||
#define IS_TMP_VAR (1<<1)
|
||||
#define IS_VAR (1<<2)
|
||||
#define IS_UNUSED (1<<3) /* Unused variable */
|
||||
|
||||
|
||||
#define EXT_TYPE_UNUSED (1<<0)
|
||||
|
||||
void init_compiler(CLS_D ELS_DC);
|
||||
void shutdown_compiler(CLS_D);
|
||||
|
||||
extern zend_op_array *(*zend_compile_files)(int mark_as_ref CLS_DC, int file_count, ...);
|
||||
|
||||
int lex_scan(zval *zendlval CLS_DC);
|
||||
void reset_scanner(CLS_D);
|
||||
void startup_scanner(CLS_D);
|
||||
void shutdown_scanner(CLS_D);
|
||||
|
||||
ZEND_API void zend_set_compiled_filename(char *new_compiled_filename);
|
||||
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename);
|
||||
ZEND_API char *zend_get_compiled_filename();
|
||||
|
||||
|
||||
/* parser-driven code generators */
|
||||
void do_binary_op(int op, znode *result, znode *op1, znode *op2 CLS_DC);
|
||||
void do_unary_op(int op, znode *result, znode *op1 CLS_DC);
|
||||
void do_binary_assign_op(int op, znode *result, znode *op1, znode *op2 CLS_DC);
|
||||
void do_assign(znode *result, znode *variable, znode *value CLS_DC);
|
||||
void do_assign_ref(znode *result, znode *lvar, znode *rvar CLS_DC);
|
||||
void fetch_simple_variable(znode *result, znode *varname, int bp CLS_DC);
|
||||
void do_indirect_references(znode *result, znode *num_references, znode *variable CLS_DC);
|
||||
void do_fetch_global_or_static_variable(znode *varname, znode *static_assignment, int fetch_type CLS_DC);
|
||||
|
||||
void fetch_array_begin(znode *result, znode *varname, znode *first_dim CLS_DC);
|
||||
void fetch_array_dim(znode *result, znode *parent, znode *dim CLS_DC);
|
||||
void do_print(znode *result, znode *arg CLS_DC);
|
||||
void do_echo(znode *arg CLS_DC);
|
||||
ZEND_API void *get_unary_op(int opcode);
|
||||
ZEND_API void *get_binary_op(int opcode);
|
||||
|
||||
void do_while_cond(znode *expr, znode *close_bracket_token CLS_DC);
|
||||
void do_while_end(znode *while_token, znode *close_bracket_token CLS_DC);
|
||||
void do_do_while_begin(CLS_D);
|
||||
void do_do_while_end(znode *do_token, znode *expr CLS_DC);
|
||||
|
||||
|
||||
void do_if_cond(znode *cond, znode *closing_bracket_token CLS_DC);
|
||||
void do_if_after_statement(znode *closing_bracket_token, unsigned char initialize CLS_DC);
|
||||
void do_if_end(CLS_D);
|
||||
|
||||
void do_for_cond(znode *expr, znode *second_semicolon_token CLS_DC);
|
||||
void do_for_before_statement(znode *cond_start, znode *second_semicolon_token CLS_DC);
|
||||
void do_for_end(znode *second_semicolon_token CLS_DC);
|
||||
|
||||
void do_pre_incdec(znode *result, znode *op1, int op CLS_DC);
|
||||
void do_post_incdec(znode *result, znode *op1, int op CLS_DC);
|
||||
|
||||
void do_begin_variable_parse(CLS_D);
|
||||
void do_end_variable_parse(int type CLS_DC);
|
||||
|
||||
void do_free(znode *op1 CLS_DC);
|
||||
|
||||
void do_init_string(znode *result);
|
||||
void do_add_char(znode *result, znode *op1, znode *op2 CLS_DC);
|
||||
void do_add_string(znode *result, znode *op1, znode *op2 CLS_DC);
|
||||
void do_add_variable(znode *result, znode *op1, znode *op2 CLS_DC);
|
||||
|
||||
void do_begin_function_declaration(znode *function_token, znode *function_name, int is_method CLS_DC);
|
||||
void do_end_function_declaration(znode *function_token CLS_DC);
|
||||
void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, unsigned char pass_type CLS_DC);
|
||||
void do_begin_function_call(znode *function_name CLS_DC);
|
||||
void do_begin_dynamic_function_call(znode *function_name CLS_DC);
|
||||
void do_begin_class_member_function_call(znode *class_name, znode *function_name CLS_DC);
|
||||
void do_end_function_call(znode *function_name, znode *result, int is_method CLS_DC);
|
||||
void do_return(znode *expr CLS_DC);
|
||||
|
||||
void do_pass_param(znode *param, int op, int offset CLS_DC);
|
||||
|
||||
|
||||
void do_boolean_or_begin(znode *expr1, znode *op_token CLS_DC);
|
||||
void do_boolean_or_end(znode *result, znode *expr1, znode *expr2, znode *op_token CLS_DC);
|
||||
void do_boolean_and_begin(znode *expr1, znode *op_token CLS_DC);
|
||||
void do_boolean_and_end(znode *result, znode *expr1, znode *expr2, znode *op_token CLS_DC);
|
||||
|
||||
void do_brk_cont(int op, znode *expr CLS_DC);
|
||||
|
||||
void do_switch_cond(znode *cond CLS_DC);
|
||||
void do_switch_end(znode *case_list CLS_DC);
|
||||
void do_case_before_statement(znode *case_list, znode *case_token, znode *case_expr CLS_DC);
|
||||
void do_case_after_statement(znode *result, znode *case_token CLS_DC);
|
||||
void do_default_before_statement(znode *case_list, znode *default_token CLS_DC);
|
||||
|
||||
void do_begin_class_declaration(znode *class_name, znode *parent_class_name CLS_DC);
|
||||
void do_end_class_declaration(CLS_D);
|
||||
void do_declare_property(znode *var_name, znode *value CLS_DC);
|
||||
|
||||
void do_fetch_property(znode *result, znode *object, znode *property CLS_DC);
|
||||
|
||||
|
||||
void do_push_object(znode *object CLS_DC);
|
||||
void do_pop_object(znode *object CLS_DC);
|
||||
|
||||
|
||||
void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode *class_name CLS_DC);
|
||||
void do_end_new_object(znode *class_name, znode *new_token CLS_DC);
|
||||
|
||||
void do_fetch_constant(znode *result, znode *constant_name, int mode CLS_DC);
|
||||
|
||||
void do_shell_exec(znode *result, znode *cmd CLS_DC);
|
||||
|
||||
void do_init_array(znode *result, znode *expr, znode *offset CLS_DC);
|
||||
void do_add_array_element(znode *result, znode *expr, znode *offset CLS_DC);
|
||||
void do_add_static_array_element(znode *result, znode *expr, znode *offset);
|
||||
void do_list_init();
|
||||
void do_list_end(znode *result, znode *expr CLS_DC);
|
||||
void do_add_list_element(znode *element CLS_DC);
|
||||
void do_new_list_begin(CLS_D);
|
||||
void do_new_list_end(CLS_D);
|
||||
|
||||
void do_cast(znode *result, znode *expr, int type CLS_DC);
|
||||
void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC);
|
||||
|
||||
void do_unset(znode *variable CLS_DC);
|
||||
void do_isset_or_isempty(int type, znode *result, znode *variable CLS_DC);
|
||||
|
||||
void do_foreach_begin(znode *foreach_token, znode *array, znode *open_brackets_token, znode *as_token CLS_DC);
|
||||
void do_foreach_cont(znode *value, znode *key, znode *as_token CLS_DC);
|
||||
void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC);
|
||||
|
||||
void do_end_heredoc(CLS_D);
|
||||
|
||||
void do_exit(znode *result, znode *message CLS_DC);
|
||||
|
||||
void do_begin_silence(znode *strudel_token CLS_DC);
|
||||
void do_end_silence(znode *strudel_token CLS_DC);
|
||||
|
||||
void do_begin_qm_op(znode *cond, znode *qm_token CLS_DC);
|
||||
void do_qm_true(znode *true_value, znode *qm_token, znode *colon_token CLS_DC);
|
||||
void do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colon_token CLS_DC);
|
||||
|
||||
void do_extended_info(CLS_D);
|
||||
void do_extended_fcall_begin(CLS_D);
|
||||
void do_extended_fcall_end(CLS_D);
|
||||
|
||||
|
||||
/* helper functions in zend-scanner.l */
|
||||
ZEND_API int require_file(zend_file_handle *file_handle CLS_DC);
|
||||
ZEND_API int require_filename(char *filename CLS_DC);
|
||||
ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...);
|
||||
ZEND_API zend_op_array *compile_string(zval *source_string CLS_DC);
|
||||
ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
|
||||
inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
|
||||
|
||||
#define INITIAL_OP_ARRAY_SIZE 1024
|
||||
|
||||
|
||||
ZEND_API void init_op_array(zend_op_array *op_array, int initial_ops_size);
|
||||
ZEND_API void destroy_op_array(zend_op_array *op_array);
|
||||
|
||||
void destroy_zend_function(zend_function *function);
|
||||
void destroy_zend_class(zend_class_entry *ce);
|
||||
zend_op *get_next_op(zend_op_array *op_array CLS_DC);
|
||||
int get_next_op_number(zend_op_array *op_array);
|
||||
int print_class(zend_class_entry *class_entry);
|
||||
void print_op_array(zend_op_array *op_array, int optimizations);
|
||||
int pass_two(zend_op_array *op_array);
|
||||
void pass_include_eval(zend_op_array *op_array);
|
||||
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
|
||||
|
||||
|
||||
int zendlex(znode *zendlval CLS_DC);
|
||||
|
||||
|
||||
#define ZEND_NOP 0
|
||||
|
||||
#define ZEND_ADD 1
|
||||
#define ZEND_SUB 2
|
||||
#define ZEND_MUL 3
|
||||
#define ZEND_DIV 4
|
||||
#define ZEND_MOD 5
|
||||
#define ZEND_SL 6
|
||||
#define ZEND_SR 7
|
||||
#define ZEND_CONCAT 8
|
||||
#define ZEND_BW_OR 9
|
||||
#define ZEND_BW_AND 10
|
||||
#define ZEND_BW_XOR 11
|
||||
#define ZEND_BW_NOT 12
|
||||
#define ZEND_BOOL_NOT 13
|
||||
#define ZEND_BOOL_XOR 14
|
||||
#define ZEND_IS_EQUAL 15
|
||||
#define ZEND_IS_NOT_EQUAL 16
|
||||
#define ZEND_IS_SMALLER 17
|
||||
#define ZEND_IS_SMALLER_OR_EQUAL 18
|
||||
#define ZEND_CAST 19
|
||||
#define ZEND_QM_ASSIGN 20
|
||||
|
||||
#define ZEND_ASSIGN_ADD 21
|
||||
#define ZEND_ASSIGN_SUB 22
|
||||
#define ZEND_ASSIGN_MUL 23
|
||||
#define ZEND_ASSIGN_DIV 24
|
||||
#define ZEND_ASSIGN_MOD 25
|
||||
#define ZEND_ASSIGN_SL 26
|
||||
#define ZEND_ASSIGN_SR 27
|
||||
#define ZEND_ASSIGN_CONCAT 28
|
||||
#define ZEND_ASSIGN_BW_OR 29
|
||||
#define ZEND_ASSIGN_BW_AND 30
|
||||
#define ZEND_ASSIGN_BW_XOR 31
|
||||
|
||||
#define ZEND_PRE_INC 32
|
||||
#define ZEND_PRE_DEC 33
|
||||
#define ZEND_POST_INC 34
|
||||
#define ZEND_POST_DEC 35
|
||||
|
||||
#define ZEND_ASSIGN 36
|
||||
#define ZEND_ASSIGN_REF 37
|
||||
|
||||
#define ZEND_ECHO_OP 38
|
||||
#define ZEND_PRINT_OP 39
|
||||
|
||||
#define ZEND_JMP 40
|
||||
#define ZEND_JMPZ 41
|
||||
#define ZEND_JMPNZ 42
|
||||
#define ZEND_JMPZNZ 43
|
||||
#define ZEND_JMPZ_EX 44
|
||||
#define ZEND_JMPNZ_EX 45
|
||||
#define ZEND_CASE 46
|
||||
#define ZEND_BRK 47
|
||||
#define ZEND_CONT 48
|
||||
#define ZEND_BOOL 49
|
||||
|
||||
#define ZEND_INIT_STRING 50
|
||||
#define ZEND_ADD_CHAR 51
|
||||
#define ZEND_ADD_STRING 52
|
||||
#define ZEND_ADD_VAR 53
|
||||
|
||||
#define ZEND_BEGIN_SILENCE 54
|
||||
#define ZEND_END_SILENCE 55
|
||||
|
||||
#define ZEND_INIT_FCALL 56
|
||||
#define ZEND_INIT_FCALL_BY_NAME 57
|
||||
#define ZEND_DO_FCALL 58
|
||||
#define ZEND_RETURN 59
|
||||
|
||||
#define ZEND_RECV 60
|
||||
#define ZEND_RECV_INIT 61
|
||||
|
||||
#define ZEND_SEND_VAL 62
|
||||
#define ZEND_SEND_VAR 63
|
||||
#define ZEND_SEND_REF 64
|
||||
|
||||
#define ZEND_NEW 65
|
||||
#define ZEND_JMP_NO_CTOR 66
|
||||
#define ZEND_FREE 67
|
||||
|
||||
#define ZEND_INIT_ARRAY 68
|
||||
#define ZEND_ADD_ARRAY_ELEMENT 69
|
||||
|
||||
#define ZEND_INCLUDE_OR_EVAL 70
|
||||
|
||||
#define ZEND_UNSET_VAR 71
|
||||
#define ZEND_UNSET_DIM_OBJ 72
|
||||
#define ZEND_ISSET_ISEMPTY 73
|
||||
|
||||
#define ZEND_FE_RESET 74
|
||||
#define ZEND_FE_FETCH 75
|
||||
|
||||
#define ZEND_EXIT 76
|
||||
|
||||
|
||||
/* the following 12 opcodes are 4 groups of 3 opcodes each, and must
|
||||
* remain in that order!
|
||||
*/
|
||||
#define ZEND_FETCH_R 77
|
||||
#define ZEND_FETCH_DIM_R 78
|
||||
#define ZEND_FETCH_OBJ_R 79
|
||||
#define ZEND_FETCH_W 80
|
||||
#define ZEND_FETCH_DIM_W 81
|
||||
#define ZEND_FETCH_OBJ_W 82
|
||||
#define ZEND_FETCH_RW 83
|
||||
#define ZEND_FETCH_DIM_RW 84
|
||||
#define ZEND_FETCH_OBJ_RW 85
|
||||
#define ZEND_FETCH_IS 86
|
||||
#define ZEND_FETCH_DIM_IS 87
|
||||
#define ZEND_FETCH_OBJ_IS 88
|
||||
|
||||
#define ZEND_FETCH_DIM_TMP_VAR 89
|
||||
#define ZEND_FETCH_CONSTANT 90
|
||||
|
||||
#define ZEND_EXT_STMT 91
|
||||
#define ZEND_EXT_FCALL_BEGIN 92
|
||||
#define ZEND_EXT_FCALL_END 93
|
||||
#define ZEND_EXT_NOP 94
|
||||
|
||||
/* end of block */
|
||||
|
||||
|
||||
|
||||
|
||||
/* global/local fetches */
|
||||
#define ZEND_FETCH_GLOBAL 0
|
||||
#define ZEND_FETCH_LOCAL 1
|
||||
#define ZEND_FETCH_STATIC 2
|
||||
|
||||
/* var status for backpatching */
|
||||
#define BP_VAR_R 0
|
||||
#define BP_VAR_W 1
|
||||
#define BP_VAR_RW 2
|
||||
#define BP_VAR_IS 3
|
||||
#define BP_VAR_NA 4 /* if not applicable */
|
||||
|
||||
|
||||
#define ZEND_INTERNAL_FUNCTION 1
|
||||
#define ZEND_USER_FUNCTION 2
|
||||
#define ZEND_OVERLOADED_FUNCTION 3
|
||||
|
||||
#define ZEND_INTERNAL_CLASS 1
|
||||
#define ZEND_USER_CLASS 2
|
||||
|
||||
#define ZEND_EVAL (1<<0)
|
||||
#define ZEND_INCLUDE (1<<1)
|
||||
|
||||
#define ZEND_ISSET (1<<0)
|
||||
#define ZEND_ISEMPTY (1<<1)
|
||||
|
||||
#define ZEND_CT (1<<0)
|
||||
#define ZEND_RT (1<<1)
|
||||
|
||||
|
||||
#define ZEND_HANDLE_FILENAME 0
|
||||
#define ZEND_HANDLE_FD 1
|
||||
#define ZEND_HANDLE_FP 2
|
||||
#define ZEND_HANDLE_ISTREAM 3
|
||||
|
||||
#endif /* _COMPILE_H */
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_constants.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_globals.h"
|
||||
|
||||
|
||||
void free_zend_constant(zend_constant *c)
|
||||
{
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
zval_dtor(&c->value);
|
||||
}
|
||||
free(c->name);
|
||||
}
|
||||
|
||||
|
||||
static int clean_non_persistent_constant(zend_constant *c)
|
||||
{
|
||||
if (c->flags & CONST_PERSISTENT) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int clean_module_constant(zend_constant *c, int *module_number)
|
||||
{
|
||||
if (c->module_number == *module_number) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void clean_module_constants(int module_number)
|
||||
{
|
||||
zend_hash_apply_with_argument(EG(zend_constants), (int (*)(void *,void *)) clean_module_constant, (void *) &module_number);
|
||||
}
|
||||
|
||||
|
||||
int zend_startup_constants(void)
|
||||
{
|
||||
#if WIN32|WINNT
|
||||
DWORD dwBuild=0;
|
||||
DWORD dwVersion = GetVersion();
|
||||
DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
||||
#endif
|
||||
|
||||
|
||||
/* ZEND_FIX: Move to PHP */
|
||||
#if 0
|
||||
#if WIN32|WINNT
|
||||
// Get build numbers for Windows NT or Win95
|
||||
if (dwVersion < 0x80000000){
|
||||
php3_os="WINNT";
|
||||
} else {
|
||||
php3_os="WIN32";
|
||||
}
|
||||
#else
|
||||
php3_os=PHP_OS;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
|
||||
|
||||
if (zend_hash_init(EG(zend_constants), 20, NULL, (void(*)(void *)) free_zend_constant, 1)==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This should go back to PHP */
|
||||
REGISTER_MAIN_STRINGL_CONSTANT("PHP_VERSION", PHP_VERSION, sizeof(PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS", php3_os, strlen(php3_os), CONST_PERSISTENT | CONST_CS);
|
||||
#endif
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
|
||||
|
||||
/* true/false constants */
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
c.value.type = IS_BOOL;
|
||||
c.flags = CONST_PERSISTENT;
|
||||
c.module_number = 0;
|
||||
|
||||
c.name = zend_strndup("TRUE",4);
|
||||
c.name_len = 5;
|
||||
c.value.value.lval = 1;
|
||||
c.value.type = IS_BOOL;
|
||||
zend_register_constant(&c);
|
||||
|
||||
c.name = zend_strndup("FALSE",5);
|
||||
c.name_len = 6;
|
||||
c.value.value.lval = 0;
|
||||
c.value.type = IS_BOOL;
|
||||
zend_register_constant(&c);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int zend_shutdown_constants(void)
|
||||
{
|
||||
zend_hash_destroy(EG(zend_constants));
|
||||
free(EG(zend_constants));
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void clean_non_persistent_constants(void)
|
||||
{
|
||||
zend_hash_apply(EG(zend_constants), (int (*)(void *)) clean_non_persistent_constant);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number)
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
c.value.type = IS_LONG;
|
||||
c.value.value.lval = lval;
|
||||
c.flags = flags;
|
||||
c.name = zend_strndup(name,name_len);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number)
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
c.value.type = IS_DOUBLE;
|
||||
c.value.value.dval = dval;
|
||||
c.flags = flags;
|
||||
c.name = zend_strndup(name,name_len);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number)
|
||||
{
|
||||
zend_constant c;
|
||||
|
||||
c.value.type = IS_STRING;
|
||||
c.value.value.str.val = strval;
|
||||
c.value.value.str.len = strlen;
|
||||
c.flags = flags;
|
||||
c.name = zend_strndup(name,name_len);
|
||||
c.name_len = name_len;
|
||||
c.module_number = module_number;
|
||||
zend_register_constant(&c);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number)
|
||||
{
|
||||
zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result)
|
||||
{
|
||||
zend_constant *c;
|
||||
char *lookup_name = estrndup(name,name_len);
|
||||
int retval;
|
||||
|
||||
zend_str_tolower(lookup_name, name_len);
|
||||
|
||||
if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
|
||||
if ((c->flags & CONST_CS) && memcmp(c->name, name, name_len)!=0) {
|
||||
retval=0;
|
||||
} else {
|
||||
retval=1;
|
||||
*result = c->value;
|
||||
zval_copy_ctor(result);
|
||||
}
|
||||
} else {
|
||||
retval=0;
|
||||
}
|
||||
|
||||
efree(lookup_name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_register_constant(zend_constant *c)
|
||||
{
|
||||
char *lowercase_name = zend_strndup(c->name, c->name_len);
|
||||
|
||||
#if 0
|
||||
printf("Registering constant for module %d\n",c->module_number);
|
||||
#endif
|
||||
|
||||
zend_str_tolower(lowercase_name, c->name_len);
|
||||
if (zend_hash_add(EG(zend_constants), lowercase_name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
|
||||
zval_dtor(&c->value);
|
||||
}
|
||||
free(lowercase_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _CONSTANTS_H
|
||||
#define _CONSTANTS_H
|
||||
|
||||
#define CONST_CS 0x1 /* Case Sensitive */
|
||||
#define CONST_PERSISTENT 0x2
|
||||
|
||||
typedef struct {
|
||||
zval value;
|
||||
int flags;
|
||||
char *name;
|
||||
uint name_len;
|
||||
int module_number;
|
||||
} zend_constant;
|
||||
|
||||
#define REGISTER_LONG_CONSTANT(name,lval,flags) zend_register_long_constant((name),sizeof(name),(lval),(flags),module_number)
|
||||
#define REGISTER_DOUBLE_CONSTANT(name,dval,flags) zend_register_double_constant((name),sizeof(name),(dval),(flags),module_number)
|
||||
#define REGISTER_STRING_CONSTANT(name,str,flags) zend_register_string_constant((name),sizeof(name),(str),(flags),module_number)
|
||||
#define REGISTER_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),module_number)
|
||||
|
||||
#define REGISTER_MAIN_LONG_CONSTANT(name,lval,flags) zend_register_long_constant((name),sizeof(name),(lval),(flags),0)
|
||||
#define REGISTER_MAIN_DOUBLE_CONSTANT(name,dval,flags) zend_register_double_constant((name),sizeof(name),(dval),(flags),0)
|
||||
#define REGISTER_MAIN_STRING_CONSTANT(name,str,flags) zend_register_string_constant((name),sizeof(name),(str),(flags),0)
|
||||
#define REGISTER_MAIN_STRINGL_CONSTANT(name,str,len,flags) zend_register_stringl_constant((name),sizeof(name),(str),(len),(flags),0)
|
||||
|
||||
void clean_module_constants(int module_number);
|
||||
void free_zend_constant(zend_constant *c);
|
||||
int zend_startup_constants(void);
|
||||
int zend_shutdown_constants(void);
|
||||
void clean_non_persistent_constants(void);
|
||||
ZEND_API int zend_get_constant(char *name, uint name_len, zval *result);
|
||||
ZEND_API void zend_register_long_constant(char *name, uint name_len, long lval, int flags, int module_number);
|
||||
ZEND_API void zend_register_double_constant(char *name, uint name_len, double dval, int flags, int module_number);
|
||||
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number);
|
||||
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number);
|
||||
ZEND_API void zend_register_constant(zend_constant *c);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_ERRORS_H
|
||||
#define _ZEND_ERRORS_H
|
||||
|
||||
#define E_CORE_ERROR (1<<0L)
|
||||
#define E_CORE_WARNING (1<<1L)
|
||||
#define E_COMPILE_ERROR (1<<2L)
|
||||
#define E_COMPILE_WARNING (1<<3L)
|
||||
#define E_PARSE (1<<4L)
|
||||
#define E_ERROR (1<<5L)
|
||||
#define E_WARNING (1<<6L)
|
||||
#define E_NOTICE (1<<7L)
|
||||
|
||||
#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)
|
||||
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
|
||||
|
||||
|
||||
#endif /* _ZEND_ERRORS_H */
|
||||
+1885
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _EXECUTE_H
|
||||
#define _EXECUTE_H
|
||||
|
||||
#include "zend_compile.h"
|
||||
#include "zend_hash.h"
|
||||
|
||||
typedef union {
|
||||
zval tmp_var;
|
||||
zval **var;
|
||||
struct {
|
||||
zval **var_dummy; /* a dummy */
|
||||
|
||||
zval *str;
|
||||
int offset;
|
||||
unsigned char type;
|
||||
} EA;
|
||||
} temp_variable;
|
||||
|
||||
|
||||
ZEND_API extern void (*zend_execute)(zend_op_array *op_array ELS_DC);
|
||||
|
||||
void init_executor(CLS_D ELS_DC);
|
||||
void shutdown_executor(ELS_D);
|
||||
void execute(zend_op_array *op_array ELS_DC);
|
||||
ZEND_API int zend_is_true(zval *op);
|
||||
ZEND_API inline void safe_free_zval_ptr(zval *p);
|
||||
ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC);
|
||||
ZEND_API inline int i_zend_is_true(zval *op);
|
||||
ZEND_API void zval_update_constant(zval *p);
|
||||
ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC);
|
||||
|
||||
#if SUPPORT_INTERACTIVE
|
||||
void execute_new_code(CLS_D);
|
||||
#endif
|
||||
|
||||
|
||||
/* services */
|
||||
ZEND_API char *get_active_function_name();
|
||||
ZEND_API char *zend_get_executed_filename(ELS_D);
|
||||
ZEND_API uint zend_get_executed_lineno(ELS_D);
|
||||
|
||||
#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
|
||||
#define zendi_zval_dtor(p) zval_dtor(&(p))
|
||||
|
||||
#define active_opline (*EG(opline_ptr))
|
||||
|
||||
|
||||
#define IS_OVERLOADED_OBJECT 1
|
||||
#define IS_STRING_OFFSET 2
|
||||
|
||||
#endif /* _EXECUTE_H */
|
||||
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_ptr_stack.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_constants.h"
|
||||
#include "zend_extensions.h"
|
||||
|
||||
|
||||
ZEND_API void (*zend_execute)(zend_op_array *op_array ELS_DC);
|
||||
|
||||
|
||||
static void (*original_sigsegv_handler)(int);
|
||||
static void zend_handle_sigsegv(int dummy)
|
||||
{
|
||||
fflush(stdout);
|
||||
signal(SIGSEGV, original_sigsegv_handler);
|
||||
/*
|
||||
printf("SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
|
||||
active_opline->opcode,
|
||||
active_opline-EG(active_op_array)->opcodes,
|
||||
get_active_function_name(),
|
||||
zend_get_executed_filename(),
|
||||
zend_get_executed_lineno());
|
||||
original_sigsegv_handler(dummy);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
static void zend_extension_activator(zend_extension *extension)
|
||||
{
|
||||
if (extension->activate) {
|
||||
extension->activate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void zend_extension_deactivator(zend_extension *extension)
|
||||
{
|
||||
if (extension->deactivate) {
|
||||
extension->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_executor(CLS_D ELS_DC)
|
||||
{
|
||||
var_uninit(&EG(uninitialized_zval));
|
||||
var_uninit(&EG(error_zval));
|
||||
EG(uninitialized_zval).refcount = 1;
|
||||
EG(uninitialized_zval).is_ref=0;
|
||||
EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
|
||||
EG(error_zval).refcount = 1;
|
||||
EG(error_zval).is_ref=0;
|
||||
EG(error_zval_ptr)=&EG(error_zval);
|
||||
zend_ptr_stack_init(&EG(function_symbol_table_stack));
|
||||
zend_ptr_stack_init(&EG(arg_types_stack));
|
||||
zend_stack_init(&EG(overloaded_objects_stack));
|
||||
original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
|
||||
EG(return_value) = &EG(global_return_value);
|
||||
EG(symtable_cache_ptr) = EG(symtable_cache)-1;
|
||||
EG(symtable_cache_limit)=EG(symtable_cache)+SYMTABLE_CACHE_SIZE-1;
|
||||
EG(no_extensions)=0;
|
||||
|
||||
EG(function_table) = CG(function_table);
|
||||
EG(class_table) = CG(class_table);
|
||||
|
||||
EG(AiCount) = 0;
|
||||
zend_ptr_stack_init(&EG(garbage));
|
||||
|
||||
EG(main_op_array) = NULL;
|
||||
zend_hash_init(&EG(symbol_table), 50, NULL, PVAL_PTR_DTOR, 0);
|
||||
EG(active_symbol_table) = &EG(symbol_table);
|
||||
|
||||
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_activator);
|
||||
|
||||
/* $GLOBALS array */
|
||||
{
|
||||
zval *globals = (zval *) emalloc(sizeof(zval));
|
||||
|
||||
globals->value.ht = &EG(symbol_table);
|
||||
globals->type = IS_ARRAY;
|
||||
globals->refcount = 1;
|
||||
globals->is_ref = 0;
|
||||
zend_hash_update(&EG(symbol_table), "GLOBALS", sizeof("GLOBALS"), &globals, sizeof(zval *), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void shutdown_executor(ELS_D)
|
||||
{
|
||||
zend_ptr_stack_destroy(&EG(function_symbol_table_stack));
|
||||
zend_ptr_stack_destroy(&EG(arg_types_stack));
|
||||
zend_stack_destroy(&EG(overloaded_objects_stack));
|
||||
|
||||
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
|
||||
zend_hash_destroy(*EG(symtable_cache_ptr));
|
||||
efree(*EG(symtable_cache_ptr));
|
||||
EG(symtable_cache_ptr)--;
|
||||
}
|
||||
zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_deactivator);
|
||||
zend_ptr_stack_destroy(&EG(garbage));
|
||||
|
||||
zend_hash_destroy(&EG(symbol_table));
|
||||
|
||||
if (EG(main_op_array)) {
|
||||
destroy_op_array(EG(main_op_array));
|
||||
efree(EG(main_op_array));
|
||||
}
|
||||
clean_non_persistent_constants();
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *get_active_function_name(ELS_D)
|
||||
{
|
||||
switch(EG(function_state_ptr)->function->type) {
|
||||
case ZEND_USER_FUNCTION: {
|
||||
char *function_name = ((zend_op_array *) EG(function_state_ptr)->function)->function_name;
|
||||
|
||||
if (function_name) {
|
||||
return function_name;
|
||||
} else {
|
||||
return "main";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_INTERNAL_FUNCTION:
|
||||
return ((zend_internal_function *) EG(function_state_ptr)->function)->function_name;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *zend_get_executed_filename(ELS_D)
|
||||
{
|
||||
return active_opline->filename;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API uint zend_get_executed_lineno(ELS_D)
|
||||
{
|
||||
return active_opline->lineno;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline void safe_free_zval_ptr(zval *p)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
if (p!=EG(uninitialized_zval_ptr)) {
|
||||
efree(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zval_ptr_dtor(zval **zval_ptr)
|
||||
{
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, (*zval_ptr)->refcount, (*zval_ptr)->refcount-1);
|
||||
#endif
|
||||
(*zval_ptr)->refcount--;
|
||||
if ((*zval_ptr)->refcount==0) {
|
||||
zval_dtor(*zval_ptr);
|
||||
safe_free_zval_ptr(*zval_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline int i_zend_is_true(zval *op)
|
||||
{
|
||||
int result;
|
||||
|
||||
switch (op->type) {
|
||||
case IS_LONG:
|
||||
case IS_BOOL:
|
||||
case IS_RESOURCE:
|
||||
result = (op->value.lval?1:0);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
result = (op->value.dval ? 1 : 0);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (op->value.str.len == 0
|
||||
|| (op->value.str.len==1 && op->value.str.val[0]=='0')) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
result = (zend_hash_num_elements(op->value.ht)?1:0);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
result = (zend_hash_num_elements(op->value.obj.properties)?1:0);
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_is_true(zval *op)
|
||||
{
|
||||
return i_zend_is_true(op);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zval_update_constant(zval *p)
|
||||
{
|
||||
if (p->type == IS_CONSTANT) {
|
||||
zval c;
|
||||
|
||||
if (!zend_get_constant(p->value.str.val, p->value.str.len, &c)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
|
||||
p->value.str.val,
|
||||
p->value.str.val);
|
||||
p->type = IS_STRING;
|
||||
} else {
|
||||
STR_FREE(p->value.str.val);
|
||||
*p = c;
|
||||
}
|
||||
p->refcount = 1;
|
||||
p->is_ref = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[])
|
||||
{
|
||||
int i;
|
||||
zval *original_return_value;
|
||||
HashTable *calling_symbol_table;
|
||||
zend_function_state function_state;
|
||||
zend_function_state *original_function_state_ptr;
|
||||
zend_op_array *original_op_array;
|
||||
zend_op **original_opline_ptr;
|
||||
zval *this=NULL;
|
||||
CLS_FETCH();
|
||||
ELS_FETCH();
|
||||
|
||||
if (object) {
|
||||
if (object->type != IS_OBJECT) {
|
||||
return FAILURE;
|
||||
}
|
||||
function_table = &object->value.obj.ce->function_table;
|
||||
/* unimplemented */
|
||||
}
|
||||
original_function_state_ptr = EG(function_state_ptr);
|
||||
zend_str_tolower(function_name->value.str.val, function_name->value.str.len);
|
||||
if (zend_hash_find(function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function_state.function)==FAILURE) {
|
||||
zend_error(E_ERROR, "Unknown function: %s()\n", function_name->value.str.val);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_ptr_stack_push(&EG(function_symbol_table_stack), function_state.function_symbol_table);
|
||||
function_state.function_symbol_table = (HashTable *) emalloc(sizeof(HashTable));
|
||||
zend_hash_init(function_state.function_symbol_table, 0, NULL, PVAL_PTR_DTOR, 0);
|
||||
|
||||
for (i=0; i<param_count; i++) {
|
||||
zval *param;
|
||||
|
||||
param = (zval *) emalloc(sizeof(zval));
|
||||
*param = *(params[i]);
|
||||
param->refcount=1;
|
||||
param->is_ref=0;
|
||||
zval_copy_ctor(param);
|
||||
zend_hash_next_index_insert_ptr(function_state.function_symbol_table, param, sizeof(zval *), NULL);
|
||||
}
|
||||
|
||||
if (object) {
|
||||
zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr;
|
||||
|
||||
var_uninit(dummy);
|
||||
dummy->refcount=1;
|
||||
dummy->is_ref=0;
|
||||
zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr);
|
||||
zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC);
|
||||
}
|
||||
|
||||
calling_symbol_table = EG(active_symbol_table);
|
||||
EG(active_symbol_table) = function_state.function_symbol_table;
|
||||
var_uninit(retval);
|
||||
if (function_state.function->type == ZEND_USER_FUNCTION) {
|
||||
original_return_value = EG(return_value);
|
||||
original_op_array = EG(active_op_array);
|
||||
EG(return_value) = retval;
|
||||
EG(active_op_array) = (zend_op_array *) function_state.function;
|
||||
original_opline_ptr = EG(opline_ptr);
|
||||
zend_execute(EG(active_op_array) ELS_CC);
|
||||
EG(active_op_array) = original_op_array;
|
||||
EG(return_value)=original_return_value;
|
||||
EG(opline_ptr) = original_opline_ptr;
|
||||
} else {
|
||||
((zend_internal_function *) function_state.function)->handler(EG(active_symbol_table), retval, &EG(regular_list), &EG(persistent_list));
|
||||
}
|
||||
zend_hash_destroy(EG(active_symbol_table));
|
||||
efree(EG(active_symbol_table));
|
||||
EG(active_symbol_table) = calling_symbol_table;
|
||||
EG(function_state_ptr) = original_function_state_ptr;
|
||||
function_state.function_symbol_table = zend_ptr_stack_pop(&EG(function_symbol_table_stack));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC)
|
||||
{
|
||||
zval pv;
|
||||
zend_op_array *new_op_array;
|
||||
zend_op_array *original_active_op_array = EG(active_op_array);
|
||||
zend_function_state *original_function_state_ptr = EG(function_state_ptr);
|
||||
int original_handle_op_arrays;
|
||||
|
||||
if (retval) {
|
||||
pv.value.str.len = strlen(str)+sizeof("return ;")-1;
|
||||
pv.value.str.val = emalloc(pv.value.str.len+1);
|
||||
strcpy(pv.value.str.val, "return ");
|
||||
strcat(pv.value.str.val, str);
|
||||
strcat(pv.value.str.val, " ;");
|
||||
} else {
|
||||
pv.value.str.len = strlen(str);
|
||||
pv.value.str.val = estrndup(str, pv.value.str.len);
|
||||
}
|
||||
pv.type = IS_STRING;
|
||||
|
||||
/*printf("Evaluating '%s'\n", pv.value.str.val);*/
|
||||
|
||||
original_handle_op_arrays = CG(handle_op_arrays);
|
||||
CG(handle_op_arrays) = 0;
|
||||
new_op_array = compile_string(&pv CLS_CC);
|
||||
CG(handle_op_arrays) = original_handle_op_arrays;
|
||||
|
||||
if (new_op_array) {
|
||||
zval dummy_retval;
|
||||
zval *original_return_value = EG(return_value);
|
||||
zend_op **original_opline_ptr = EG(opline_ptr);
|
||||
|
||||
EG(return_value) = (retval?retval:&dummy_retval);
|
||||
var_reset(EG(return_value));
|
||||
EG(active_op_array) = new_op_array;
|
||||
EG(no_extensions)=1;
|
||||
zend_execute(new_op_array ELS_CC);
|
||||
EG(no_extensions)=0;
|
||||
EG(opline_ptr) = original_opline_ptr;
|
||||
EG(active_op_array) = original_active_op_array;
|
||||
EG(function_state_ptr) = original_function_state_ptr;
|
||||
destroy_op_array(new_op_array);
|
||||
efree(new_op_array);
|
||||
EG(return_value) = original_return_value;
|
||||
if (!retval) {
|
||||
zval_dtor(&dummy_retval);
|
||||
}
|
||||
} else {
|
||||
printf("Failed executing:\n%s\n", str);
|
||||
}
|
||||
zval_dtor(&pv);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC)
|
||||
{
|
||||
zval *variable_ptr = *variable_ptr_ptr;
|
||||
zval *value_ptr;
|
||||
|
||||
|
||||
if (!value_ptr_ptr) {
|
||||
zend_error(E_ERROR, "Cannot create references to string offsets nor overloaded objects");
|
||||
return;
|
||||
}
|
||||
|
||||
value_ptr = *value_ptr_ptr;
|
||||
if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
|
||||
variable_ptr_ptr = &EG(uninitialized_zval_ptr);
|
||||
} else if (variable_ptr!=value_ptr) {
|
||||
variable_ptr->refcount--;
|
||||
if (variable_ptr->refcount==0) {
|
||||
zendi_zval_dtor(*variable_ptr);
|
||||
efree(variable_ptr);
|
||||
}
|
||||
|
||||
if (!value_ptr->is_ref) {
|
||||
/* break it away */
|
||||
value_ptr->refcount--;
|
||||
if (value_ptr->refcount>0) {
|
||||
*value_ptr_ptr = (zval *) emalloc(sizeof(zval));
|
||||
**value_ptr_ptr = *value_ptr;
|
||||
value_ptr = *value_ptr_ptr;
|
||||
zendi_zval_copy_ctor(*value_ptr);
|
||||
}
|
||||
value_ptr->refcount=1;
|
||||
value_ptr->is_ref=1;
|
||||
}
|
||||
|
||||
*variable_ptr_ptr = value_ptr;
|
||||
value_ptr->refcount++;
|
||||
} else {
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
if (result && (result->op_type != IS_UNUSED)) {
|
||||
Ts[result->u.var].var = variable_ptr_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if SUPPORT_INTERACTIVE
|
||||
void execute_new_code(CLS_D)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
if (!EG(interactive)
|
||||
|| CG(active_op_array)->backpatch_count>0) {
|
||||
|
||||
return;
|
||||
}
|
||||
CG(active_op_array)->start_op_number = CG(active_op_array)->last_executed_op_number;
|
||||
CG(active_op_array)->end_op_number = CG(active_op_array)->last;
|
||||
EG(active_op_array) = CG(active_op_array);
|
||||
zend_execute(CG(active_op_array) ELS_CC);
|
||||
CG(active_op_array)->start_op_number = CG(active_op_array)->last_executed_op_number;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend_extensions.h"
|
||||
|
||||
ZEND_API zend_llist zend_extensions;
|
||||
static int last_resource_number;
|
||||
|
||||
int zend_load_extensions(char **extension_paths)
|
||||
{
|
||||
char **p = extension_paths;
|
||||
|
||||
if (!p) {
|
||||
return SUCCESS;
|
||||
}
|
||||
while (*p) {
|
||||
if (zend_load_extension(*p)==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int zend_load_extension(char *path)
|
||||
{
|
||||
#if ZEND_EXTENSIONS_SUPPORT
|
||||
DL_HANDLE handle;
|
||||
zend_extension extension, *new_extension;
|
||||
zend_extension_version_info *extension_version_info;
|
||||
|
||||
handle = DL_LOAD(path);
|
||||
if (!handle) {
|
||||
zend_printf("Failed loading %s\n", path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
extension_version_info = (zend_extension_version_info *) DL_FETCH_SYMBOL(handle, "extension_version_info");
|
||||
new_extension = (zend_extension *) DL_FETCH_SYMBOL(handle, "zend_extension_entry");
|
||||
if (!extension_version_info || !new_extension) {
|
||||
zend_printf("%s doesn't appear to be a valid Zend extension\n", path);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
|
||||
zend_printf("%s requires Zend version %s or later\n"
|
||||
"Current version %s, API version %d\n",
|
||||
new_extension->name,
|
||||
extension_version_info->required_zend_version,
|
||||
ZEND_VERSION,
|
||||
ZEND_EXTENSION_API_NO);
|
||||
return FAILURE;
|
||||
} else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
|
||||
/* we may be able to allow for downwards compatability in some harmless cases. */
|
||||
zend_printf("%s is outdated (API version %d, current version %d)\n"
|
||||
"Contact %s at %s for a later version of this module.\n",
|
||||
new_extension->name,
|
||||
extension_version_info->zend_extension_api_no,
|
||||
ZEND_EXTENSION_API_NO,
|
||||
new_extension->author,
|
||||
new_extension->URL);
|
||||
return FAILURE;
|
||||
} else if (ZTS_V!=extension_version_info->thread_safe) {
|
||||
zend_printf("Cannot load %s - it %s thread safe, whereas Zend %s\n",
|
||||
new_extension->name,
|
||||
(extension_version_info->thread_safe?"is":"isn't"),
|
||||
(ZTS_V?"is":"isn't"));
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (new_extension->startup) {
|
||||
new_extension->startup(new_extension);
|
||||
}
|
||||
extension = *new_extension;
|
||||
extension.handle = handle;
|
||||
|
||||
zend_llist_add_element(&zend_extensions, &extension);
|
||||
|
||||
/*zend_printf("Loaded %s, version %s\n", extension.name, extension.version);*/
|
||||
|
||||
zend_append_version_info(&extension);
|
||||
return SUCCESS;
|
||||
#else
|
||||
zend_printf("Extensions are not supported on this platform.\n");
|
||||
return FAILURE
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void zend_extension_dtor(zend_extension *extension)
|
||||
{
|
||||
#if ZEND_EXTENSIONS_SUPPORT
|
||||
if (extension->shutdown) {
|
||||
extension->shutdown(extension);
|
||||
}
|
||||
DL_UNLOAD(extension->handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_get_resource_handle(zend_extension *extension)
|
||||
{
|
||||
if (last_resource_number<4) {
|
||||
extension->resource_number = last_resource_number;
|
||||
return last_resource_number;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_EXTENSIONS_H
|
||||
#define _ZEND_EXTENSIONS_H
|
||||
|
||||
#include "zend_compile.h"
|
||||
|
||||
#define ZEND_EXTENSION_API_NO 2
|
||||
|
||||
typedef struct {
|
||||
int zend_extension_api_no;
|
||||
char *required_zend_version;
|
||||
unsigned char thread_safe;
|
||||
} zend_extension_version_info;
|
||||
|
||||
|
||||
typedef struct _zend_extension zend_extension;
|
||||
|
||||
struct _zend_extension {
|
||||
char *name;
|
||||
char *version;
|
||||
char *author;
|
||||
char *URL;
|
||||
char *copyright;
|
||||
|
||||
void (*startup)(zend_extension *extension);
|
||||
void (*shutdown)(zend_extension *extension);
|
||||
void (*activate)();
|
||||
void (*deactivate)();
|
||||
|
||||
void (*op_array_handler)(zend_op_array *op_array);
|
||||
|
||||
void (*statement_handler)(zend_op_array *op_array);
|
||||
void (*fcall_begin_handler)(zend_op_array *op_array);
|
||||
void (*fcall_end_handler)(zend_op_array *op_array);
|
||||
|
||||
void (*op_array_ctor)(void **resource);
|
||||
void (*op_array_dtor)(void **resource);
|
||||
|
||||
void *reserved1;
|
||||
void *reserved2;
|
||||
void *reserved3;
|
||||
void *reserved4;
|
||||
void *reserved5;
|
||||
void *reserved6;
|
||||
void *reserved7;
|
||||
void *reserved8;
|
||||
|
||||
DL_HANDLE handle;
|
||||
int resource_number;
|
||||
};
|
||||
|
||||
|
||||
ZEND_API int zend_get_resource_handle();
|
||||
|
||||
#ifdef ZTS
|
||||
#define ZTS_V 1
|
||||
#else
|
||||
#define ZTS_V 0
|
||||
#endif
|
||||
|
||||
|
||||
#define ZEND_EXTENSION() \
|
||||
ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, "0.80A", ZTS_V }
|
||||
|
||||
#define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
|
||||
|
||||
|
||||
ZEND_API extern zend_llist zend_extensions;
|
||||
|
||||
void zend_extension_dtor(zend_extension *extension);
|
||||
int zend_load_extension(char *path);
|
||||
int zend_load_extensions(char **extension_paths);
|
||||
void zend_append_version_info(zend_extension *extension);
|
||||
|
||||
#endif /* _ZEND_EXTENSIONS_H */
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_GLOBALS_H
|
||||
#define _ZEND_GLOBALS_H
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "zend_stack.h"
|
||||
#include "zend_ptr_stack.h"
|
||||
#include "zend_hash.h"
|
||||
#include "zend_llist.h"
|
||||
|
||||
#undef ZTS
|
||||
|
||||
#ifdef ZTS
|
||||
#include "SAPI.h"
|
||||
|
||||
extern int compiler_globals_id;
|
||||
extern int executor_globals_id;
|
||||
#endif
|
||||
|
||||
typedef struct _zend_compiler_globals zend_compiler_globals;
|
||||
typedef struct _zend_executor_globals zend_executor_globals;
|
||||
typedef struct _zend_alloc_globals zend_alloc_globals;
|
||||
|
||||
#define SYMTABLE_CACHE_SIZE 32
|
||||
|
||||
|
||||
/* Compiler */
|
||||
#ifdef ZTS
|
||||
# define CLS_D zend_compiler_globals *compiler_globals
|
||||
# define CLS_DC , CLS_D
|
||||
# define CLS_C compiler_globals
|
||||
# define CLS_CC , CLS_C
|
||||
# define CG(v) (((zend_compiler_globals *) compiler_globals)->v)
|
||||
# define CLS_FETCH() zend_compiler_globals *compiler_globals = ts_resource(compiler_globals_id)
|
||||
# define YYPARSE_PARAM compiler_globals
|
||||
# define YYLEX_PARAM compiler_globals
|
||||
int zendparse(void *compiler_globals);
|
||||
#else
|
||||
# define CLS_D
|
||||
# define CLS_DC
|
||||
# define CLS_C
|
||||
# define CLS_CC
|
||||
# define CG(v) (compiler_globals.v)
|
||||
# define CLS_FETCH()
|
||||
extern ZEND_API zend_compiler_globals compiler_globals;
|
||||
int zendparse();
|
||||
#endif
|
||||
|
||||
|
||||
/* Executor */
|
||||
#ifdef ZTS
|
||||
# define ELS_D zend_executor_globals *executor_globals
|
||||
# define ELS_DC , ELS_D
|
||||
# define ELS_C executor_globals
|
||||
# define ELS_CC , ELS_C
|
||||
# define EG(v) (executor_globals->v)
|
||||
# define ELS_FETCH() zend_executor_globals *executor_globals = ts_resource(executor_globals_id)
|
||||
#else
|
||||
# define ELS_D
|
||||
# define ELS_DC
|
||||
# define ELS_C
|
||||
# define ELS_CC
|
||||
# define EG(v) (executor_globals.v)
|
||||
# define ELS_FETCH()
|
||||
extern ZEND_API zend_executor_globals executor_globals;
|
||||
#endif
|
||||
|
||||
|
||||
/* Memory Manager */
|
||||
#ifdef ZTS
|
||||
# define ALS_D zend_alloc_globals *alloc_globals
|
||||
# define ALS_DC , ALS_D
|
||||
# define ALS_C alloc_globals
|
||||
# define ALS_CC , ALS_C
|
||||
# define AG(v) (((zend_alloc_globals *) alloc_globals)->v)
|
||||
# define ALS_FETCH() zend_alloc_globals *alloc_globals = ts_resource(alloc_globals_id)
|
||||
#else
|
||||
# define ALS_D
|
||||
# define ALS_DC
|
||||
# define ALS_C
|
||||
# define ALS_CC
|
||||
# define AG(v) (alloc_globals.v)
|
||||
# define ALS_FETCH()
|
||||
#endif
|
||||
|
||||
|
||||
#include "zend_compile.h"
|
||||
#include "zend_execute.h"
|
||||
|
||||
struct _zend_compiler_globals {
|
||||
zend_stack bp_stack;
|
||||
zend_stack switch_cond_stack;
|
||||
zend_stack object_stack;
|
||||
|
||||
zend_class_entry class_entry, *active_class_entry;
|
||||
|
||||
/* variables for list() compilation */
|
||||
zend_llist list_llist;
|
||||
zend_llist dimension_llist;
|
||||
|
||||
zend_stack function_call_stack;
|
||||
|
||||
char *compiled_filename;
|
||||
|
||||
int zend_lineno;
|
||||
char *heredoc;
|
||||
int heredoc_len;
|
||||
|
||||
zend_op_array *active_op_array;
|
||||
|
||||
HashTable *function_table; /* function symbol table */
|
||||
HashTable *class_table; /* class table */
|
||||
|
||||
zend_llist filenames_list;
|
||||
|
||||
unsigned char short_tags;
|
||||
unsigned char asp_tags;
|
||||
|
||||
/* For extensions support */
|
||||
unsigned char extended_info; /* generate extension information for debugger/profiler */
|
||||
unsigned char handle_op_arrays; /* run op_arrays through op_array handlers */
|
||||
};
|
||||
|
||||
|
||||
struct _zend_executor_globals {
|
||||
zval *return_value;
|
||||
|
||||
zval uninitialized_zval;
|
||||
zval *uninitialized_zval_ptr;
|
||||
|
||||
zval error_zval;
|
||||
zval *error_zval_ptr;
|
||||
|
||||
zend_function_state *function_state_ptr;
|
||||
zend_ptr_stack function_symbol_table_stack;
|
||||
zend_ptr_stack arg_types_stack;
|
||||
zend_stack overloaded_objects_stack;
|
||||
zval global_return_value;
|
||||
|
||||
/* symbol table cache */
|
||||
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
|
||||
HashTable **symtable_cache_limit;
|
||||
HashTable **symtable_cache_ptr;
|
||||
|
||||
zend_op **opline_ptr;
|
||||
|
||||
HashTable *active_symbol_table;
|
||||
HashTable symbol_table; /* main symbol table */
|
||||
|
||||
jmp_buf bailout;
|
||||
|
||||
int error_reporting;
|
||||
|
||||
zend_op_array *active_op_array;
|
||||
zend_op_array *main_op_array;
|
||||
|
||||
HashTable *function_table; /* function symbol table */
|
||||
HashTable *class_table; /* class table */
|
||||
HashTable *zend_constants; /* constants table */
|
||||
|
||||
long precision;
|
||||
|
||||
unsigned int AiCount;
|
||||
|
||||
zend_ptr_stack garbage;
|
||||
|
||||
/* for extended information support */
|
||||
unsigned char no_extensions;
|
||||
|
||||
HashTable regular_list;
|
||||
HashTable persistent_list;
|
||||
|
||||
#if SUPPORT_INTERACTIVE
|
||||
int interactive;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct _zend_alloc_globals {
|
||||
mem_header *head; /* standard list */
|
||||
mem_header *phead; /* persistent list */
|
||||
void *cache[MAX_CACHED_MEMORY][MAX_CACHED_ENTRIES];
|
||||
unsigned char cache_count[MAX_CACHED_MEMORY];
|
||||
|
||||
# if MEMORY_LIMIT
|
||||
unsigned int allocated_memory;
|
||||
unsigned char memory_exhausted;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ZEND_GLOBALS_H */
|
||||
+1163
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HASH_
|
||||
#define _HASH_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define HASH_KEY_IS_STRING 1
|
||||
#define HASH_KEY_IS_LONG 2
|
||||
#define HASH_KEY_NON_EXISTANT 3
|
||||
|
||||
#define HASH_UPDATE (1<<0)
|
||||
#define HASH_ADD (1<<1)
|
||||
#define HASH_NEXT_INSERT (1<<2)
|
||||
#define HASH_ADD_PTR (1<<3)
|
||||
|
||||
#define HASH_DEL_KEY 0
|
||||
#define HASH_DEL_INDEX 1
|
||||
|
||||
struct hashtable;
|
||||
|
||||
typedef struct bucket {
|
||||
ulong h; /* Used for numeric indexing */
|
||||
uint nKeyLength;
|
||||
void *pData;
|
||||
void *pDataPtr;
|
||||
char bIsPointer;
|
||||
struct bucket *pListNext;
|
||||
struct bucket *pListLast;
|
||||
struct bucket *pNext;
|
||||
char arKey[1]; /* Must be last element */
|
||||
} Bucket;
|
||||
|
||||
typedef struct hashtable {
|
||||
uint nTableSize;
|
||||
uint nHashSizeIndex;
|
||||
uint nNumOfElements;
|
||||
ulong nNextFreeElement;
|
||||
ulong(*pHashFunction) (char *arKey, uint nKeyLength);
|
||||
Bucket *pInternalPointer; /* Used for element traversal */
|
||||
Bucket *pListHead;
|
||||
Bucket *pListTail;
|
||||
Bucket **arBuckets;
|
||||
void (*pDestructor) (void *pData);
|
||||
unsigned char persistent;
|
||||
} HashTable;
|
||||
|
||||
|
||||
/* startup/shutdown */
|
||||
ZEND_API int zend_hash_init(HashTable *ht, uint nSize, ulong(*pHashFunction) (char *arKey, uint nKeyLength), void (*pDestructor) (void *pData), int persistent);
|
||||
ZEND_API void zend_hash_destroy(HashTable *ht);
|
||||
|
||||
ZEND_API void zend_hash_clean(HashTable *ht);
|
||||
|
||||
/* additions/updates/changes */
|
||||
ZEND_API int zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest,int flag);
|
||||
#define zend_hash_update(ht,arKey,nKeyLength,pData,nDataSize,pDest) \
|
||||
zend_hash_add_or_update(ht,arKey,nKeyLength,pData,nDataSize,pDest,HASH_UPDATE)
|
||||
#define zend_hash_add(ht,arKey,nKeyLength,pData,nDataSize,pDest) \
|
||||
zend_hash_add_or_update(ht,arKey,nKeyLength,pData,nDataSize,pDest,HASH_ADD)
|
||||
#define zend_hash_update_ptr(ht,arKey,nKeyLength,pData,nDataSize,pDest) \
|
||||
zend_hash_add_or_update(ht,arKey,nKeyLength,pData,0,pDest,(HASH_UPDATE|HASH_ADD_PTR))
|
||||
|
||||
ZEND_API int zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest,int flag);
|
||||
#define zend_hash_quick_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest) \
|
||||
zend_hash_quick_add_or_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest,HASH_UPDATE)
|
||||
#define zend_hash_quick_add(ht,arKey,nKeyLength,h,pData,nDataSize,pDest) \
|
||||
zend_hash_quick_add_or_update(ht,arKey,nKeyLength,h,pData,nDataSize,pDest,HASH_ADD)
|
||||
#define zend_hash_quick_update_ptr(ht,arKey,nKeyLength,h,pData,nDataSize,pDest) \
|
||||
zend_hash_quick_add_or_update(ht,arKey,nKeyLength,h,pData,0,pDest,HASH_UPDATE|HASH_ADD_PTR)
|
||||
|
||||
ZEND_API int zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag);
|
||||
#define zend_hash_index_update(ht,h,pData,nDataSize,pDest) \
|
||||
zend_hash_index_update_or_next_insert(ht,h,pData,nDataSize,pDest,HASH_UPDATE)
|
||||
#define zend_hash_next_index_insert(ht,pData,nDataSize,pDest) \
|
||||
zend_hash_index_update_or_next_insert(ht,0,pData,nDataSize,pDest,HASH_NEXT_INSERT)
|
||||
#define zend_hash_next_index_insert_ptr(ht,pData,nDataSize,pDest) \
|
||||
zend_hash_index_update_or_next_insert(ht,0,pData,nDataSize,pDest,HASH_NEXT_INSERT|HASH_ADD_PTR)
|
||||
|
||||
ZEND_API int zend_hash_pointer_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData);
|
||||
|
||||
ZEND_API int zend_hash_pointer_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, int flag);
|
||||
#define zend_hash_pointer_index_update(ht,h,pData) \
|
||||
zend_hash_pointer_index_update_or_next_insert(ht,h,pData,HASH_UPDATE)
|
||||
#define zend_hash_next_index_pointer_insert(ht,pData) \
|
||||
zend_hash_pointer_index_update_or_next_insert(ht,0,pData,HASH_NEXT_INSERT)
|
||||
ZEND_API void zend_hash_apply(HashTable *ht,int (*destruct) (void *));
|
||||
ZEND_API void zend_hash_apply_with_argument(HashTable *ht,int (*destruct) (void *, void *), void *);
|
||||
|
||||
|
||||
|
||||
/* Deletes */
|
||||
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
|
||||
#define zend_hash_del(ht,arKey,nKeyLength) \
|
||||
zend_hash_del_key_or_index(ht,arKey,nKeyLength,0,HASH_DEL_KEY)
|
||||
#define zend_hash_index_del(ht,h) \
|
||||
zend_hash_del_key_or_index(ht,NULL,0,h,HASH_DEL_INDEX)
|
||||
|
||||
ZEND_API ulong zend_get_hash_value(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
|
||||
/* Data retreival */
|
||||
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_hash_quick_find(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
|
||||
ZEND_API int zend_hash_index_find(HashTable *ht, ulong h, void **pData);
|
||||
|
||||
/* Misc */
|
||||
ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h);
|
||||
ZEND_API int zend_hash_is_pointer(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_hash_index_is_pointer(HashTable *ht, ulong h);
|
||||
ZEND_API ulong zend_hash_next_free_element(HashTable *ht);
|
||||
|
||||
/* traversing */
|
||||
ZEND_API void zend_hash_move_forward(HashTable *ht);
|
||||
ZEND_API void zend_hash_move_backwards(HashTable *ht);
|
||||
ZEND_API int zend_hash_get_current_key(HashTable *ht, char **str_index, ulong *num_index);
|
||||
ZEND_API int zend_hash_get_current_data(HashTable *ht, void **pData);
|
||||
ZEND_API void zend_hash_internal_pointer_reset(HashTable *ht);
|
||||
ZEND_API void zend_hash_internal_pointer_end(HashTable *ht);
|
||||
|
||||
/* Copying, merging and sorting */
|
||||
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, void (*pCopyConstructor) (void *pData), void *tmp, uint size);
|
||||
ZEND_API void zend_hash_merge(HashTable *target, HashTable *source, void (*pCopyConstructor) (void *pData), void *tmp, uint size);
|
||||
ZEND_API int zend_hash_sort(HashTable *ht, int (*compar) (const void *, const void *), int renumber);
|
||||
ZEND_API int zend_hash_minmax(HashTable *ht, int (*compar) (const void *, const void *), int flag, void **pData);
|
||||
|
||||
ZEND_API int zend_hash_num_elements(HashTable *ht);
|
||||
|
||||
|
||||
ZEND_API ulong hashpjw(char *arKey, uint nKeyLength);
|
||||
|
||||
#if DEBUG
|
||||
/* debug */
|
||||
void zend_hash_display_pListTail(HashTable *ht);
|
||||
void zend_hash_display(HashTable *ht);
|
||||
#endif
|
||||
|
||||
#endif /* _HASH_ */
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_highlight.h"
|
||||
#include "zend_ptr_stack.h"
|
||||
#include "zend_globals.h"
|
||||
|
||||
extern char *zendtext;
|
||||
extern int zendleng;
|
||||
|
||||
|
||||
static void html_putc(char c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\n':
|
||||
ZEND_PUTS("<br>");
|
||||
break;
|
||||
case '<':
|
||||
ZEND_PUTS("<");
|
||||
break;
|
||||
case '>':
|
||||
ZEND_PUTS(">");
|
||||
break;
|
||||
case '&':
|
||||
ZEND_PUTS("&");
|
||||
break;
|
||||
case ' ':
|
||||
ZEND_PUTS(" ");
|
||||
break;
|
||||
case '\t':
|
||||
ZEND_PUTS(" ");
|
||||
break;
|
||||
default:
|
||||
ZEND_PUTC(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void html_puts(char *s, uint len)
|
||||
{
|
||||
register char *ptr=s, *end=s+len;
|
||||
|
||||
while (ptr<end) {
|
||||
html_putc(*ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini)
|
||||
{
|
||||
zval token;
|
||||
int token_type;
|
||||
char *last_color = syntax_highlighter_ini->highlight_html;
|
||||
char *next_color;
|
||||
int in_string=0;
|
||||
CLS_FETCH();
|
||||
|
||||
zend_printf("<font color=\"%s\">\n", last_color);
|
||||
/* highlight stuff coming back from zendlex() */
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token CLS_CC))) {
|
||||
switch (token_type) {
|
||||
case INLINE_HTML:
|
||||
next_color = syntax_highlighter_ini->highlight_html;
|
||||
break;
|
||||
case ZEND_COMMENT:
|
||||
next_color = syntax_highlighter_ini->highlight_comment;
|
||||
break;
|
||||
case PHP_OPEN_TAG:
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
break;
|
||||
case PHP_CLOSE_TAG:
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
break;
|
||||
case CONSTANT_ENCAPSED_STRING:
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
break;
|
||||
case '"':
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
in_string = !in_string;
|
||||
break;
|
||||
case T_WHITESPACE:
|
||||
html_puts(zendtext, zendleng); /* no color needed */
|
||||
token.type = 0;
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (token.type==0) {
|
||||
next_color = syntax_highlighter_ini->highlight_keyword;
|
||||
} else {
|
||||
if (in_string) {
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
} else {
|
||||
next_color = syntax_highlighter_ini->highlight_default;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (last_color != next_color) {
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
zend_printf("</font>");
|
||||
}
|
||||
last_color = next_color;
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
zend_printf("<font color=\"%s\">", last_color);
|
||||
}
|
||||
}
|
||||
switch (token_type) {
|
||||
case DOLLAR_OPEN_CURLY_BRACES:
|
||||
html_puts("{", 1);
|
||||
break;
|
||||
default:
|
||||
html_puts(zendtext, zendleng);
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.type == IS_STRING) {
|
||||
switch (token_type) {
|
||||
case PHP_OPEN_TAG:
|
||||
case PHP_CLOSE_TAG:
|
||||
case T_WHITESPACE:
|
||||
break;
|
||||
default:
|
||||
efree(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
token.type = 0;
|
||||
}
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
zend_printf("</font>\n");
|
||||
}
|
||||
zend_printf("</font>\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _HIGHLIGHT_H
|
||||
#define _HIGHLIGHT_H
|
||||
|
||||
#define HL_COMMENT_COLOR "#FF8000" /* orange */
|
||||
#define HL_DEFAULT_COLOR "#0000BB" /* blue */
|
||||
#define HL_HTML_COLOR "#000000" /* black */
|
||||
#define HL_STRING_COLOR "#DD0000" /* red */
|
||||
#define HL_BG_COLOR "#FFFFFF" /* white */
|
||||
#define HL_KEYWORD_COLOR "#007700" /* green */
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *highlight_html;
|
||||
char *highlight_comment;
|
||||
char *highlight_default;
|
||||
char *highlight_string;
|
||||
char *highlight_keyword;
|
||||
} zend_syntax_highlighter_ini;
|
||||
|
||||
void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini);
|
||||
|
||||
int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini);
|
||||
int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini);
|
||||
|
||||
extern zend_syntax_highlighter_ini syntax_highlighter_ini;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* This indenter doesn't really work, it's here for no particular reason. */
|
||||
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_indent.h"
|
||||
|
||||
extern char *zendtext;
|
||||
extern int zendleng;
|
||||
|
||||
static void handle_whitespace(int *emit_whitespace)
|
||||
{
|
||||
unsigned char c;
|
||||
int i;
|
||||
|
||||
for (c=0; c<128; c++) {
|
||||
if (emit_whitespace[c]>0) {
|
||||
for (i=0; i<emit_whitespace[c]; i++) {
|
||||
zend_write(&c, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(emit_whitespace, 0, sizeof(int)*256);
|
||||
}
|
||||
|
||||
|
||||
void zend_indent()
|
||||
{
|
||||
zval token;
|
||||
int token_type;
|
||||
int in_string=0;
|
||||
int nest_level=0;
|
||||
int emit_whitespace[256];
|
||||
int i;
|
||||
CLS_FETCH();
|
||||
|
||||
memset(emit_whitespace, 0, sizeof(int)*256);
|
||||
|
||||
/* highlight stuff coming back from zendlex() */
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token CLS_CC))) {
|
||||
switch (token_type) {
|
||||
case INLINE_HTML:
|
||||
zend_write(zendtext, zendleng);
|
||||
break;
|
||||
case T_WHITESPACE: {
|
||||
token.type = 0;
|
||||
/* eat whitespace, emit newlines */
|
||||
for (i=0; i<zendleng; i++) {
|
||||
emit_whitespace[(unsigned char) zendtext[i]]++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
in_string = !in_string;
|
||||
/* break missing intentionally */
|
||||
default:
|
||||
if (token.type==0) {
|
||||
/* keyword */
|
||||
switch(token_type) {
|
||||
case ',':
|
||||
ZEND_PUTS(", ");
|
||||
goto dflt_printout;
|
||||
break;
|
||||
case '{':
|
||||
nest_level++;
|
||||
if (emit_whitespace['\n']>0) {
|
||||
ZEND_PUTS(" {\n");
|
||||
memset(emit_whitespace, 0, sizeof(int)*256);
|
||||
} else {
|
||||
ZEND_PUTS("{");
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
nest_level--;
|
||||
if (emit_whitespace['\n']==0) {
|
||||
ZEND_PUTS("\n");
|
||||
}
|
||||
for (i=0; i<nest_level; i++) {
|
||||
ZEND_PUTS(" ");
|
||||
}
|
||||
goto dflt_printout;
|
||||
break;
|
||||
dflt_printout:
|
||||
default:
|
||||
if (emit_whitespace['\n']>0) {
|
||||
for (i=0; i<emit_whitespace['\n']; i++) {
|
||||
ZEND_PUTS("\n");
|
||||
}
|
||||
memset(emit_whitespace, 0, sizeof(int)*256);
|
||||
for (i=0; i<nest_level; i++) {
|
||||
ZEND_PUTS(" ");
|
||||
}
|
||||
} else {
|
||||
handle_whitespace(emit_whitespace);
|
||||
}
|
||||
zend_write(zendtext, zendleng);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
handle_whitespace(emit_whitespace);
|
||||
if (in_string) {
|
||||
zend_write(zendtext, zendleng);
|
||||
/* a part of a string */
|
||||
} else {
|
||||
zend_write(zendtext, zendleng);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (token.type == IS_STRING) {
|
||||
switch (token_type) {
|
||||
case PHP_OPEN_TAG:
|
||||
case PHP_CLOSE_TAG:
|
||||
case T_WHITESPACE:
|
||||
break;
|
||||
default:
|
||||
efree(token.value.str.val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
token.type = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef _ZEND_INDENT_H
|
||||
#define _ZEND_INDENT_H
|
||||
|
||||
void zend_indent();
|
||||
|
||||
#endif /* _ZEND_INDENT_H */
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to the Zend license, that is bundled |
|
||||
| with this package in the file LICENSE. If you did not receive a |
|
||||
| copy of the Zend license, please mail us at zend@zend.com so we can |
|
||||
| send you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_list.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_globals.h"
|
||||
|
||||
#if 0
|
||||
#if HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#if MSVC5
|
||||
#if !(APACHE)
|
||||
#define NEEDRDH 1
|
||||
#endif
|
||||
#include "win32/readdir.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
int le_index_ptr;
|
||||
|
||||
static inline int zend_list_do_insert(HashTable *list,void *ptr, int type)
|
||||
{
|
||||
int index;
|
||||
list_entry le;
|
||||
|
||||
index = zend_hash_next_free_element(list);
|
||||
|
||||
if (index==0) index++;
|
||||
|
||||
le.ptr=ptr;
|
||||
le.type=type;
|
||||
le.refcount=1;
|
||||
zend_hash_index_update(list, index, (void *) &le, sizeof(list_entry), NULL);
|
||||
return index;
|
||||
}
|
||||
|
||||
static inline int zend_list_do_delete(HashTable *list,int id)
|
||||
{
|
||||
list_entry *le;
|
||||
ELS_FETCH();
|
||||
|
||||
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
|
||||
// printf("del(%d): %d->%d\n", id, le->refcount, le->refcount-1);
|
||||
if (--le->refcount<=0) {
|
||||
return zend_hash_index_del(&EG(regular_list), id);
|
||||
} else {
|
||||
return SUCCESS;
|
||||
}
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void *zend_list_do_find(HashTable *list,int id, int *type)
|
||||
{
|
||||
list_entry *le;
|
||||
|
||||
if (zend_hash_index_find(list, id, (void **) &le)==SUCCESS) {
|
||||
*type = le->type;
|
||||
return le->ptr;
|
||||
} else {
|
||||
*type = -1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int zend_list_insert(void *ptr, int type)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_insert(&EG(regular_list), ptr, type);
|
||||
}
|
||||
|
||||
|
||||
int zend_plist_insert(void *ptr, int type)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_insert(&EG(persistent_list), ptr, type);
|
||||
}
|
||||
|
||||
|
||||
int zend_list_delete(int id)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_delete(&EG(regular_list), id);
|
||||
}
|
||||
|
||||
|
||||
int zend_list_addref(int id)
|
||||
{
|
||||
list_entry *le;
|
||||
ELS_FETCH();
|
||||
|
||||
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
|
||||
// printf("add(%d): %d->%d\n", id, le->refcount, le->refcount+1);
|
||||
le->refcount++;
|
||||
return SUCCESS;
|
||||
} else {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
int zend_plist_delete(int id)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_delete(&EG(persistent_list), id);
|
||||
}
|
||||
|
||||
|
||||
void *zend_list_find(int id, int *type)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_find(&EG(regular_list), id, type);
|
||||
}
|
||||
|
||||
|
||||
void *zend_plist_find(int id, int *type)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_list_do_find(&EG(persistent_list), id, type);
|
||||
}
|
||||
|
||||
|
||||
void list_entry_destructor(void *ptr)
|
||||
{
|
||||
list_entry *le = (list_entry *) ptr;
|
||||
list_destructors_entry *ld;
|
||||
|
||||
if (zend_hash_index_find(&list_destructors,le->type,(void **) &ld)==SUCCESS) {
|
||||
if (ld->list_destructor) {
|
||||
(ld->list_destructor)(le->ptr);
|
||||
}
|
||||
} else {
|
||||
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)",le->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void plist_entry_destructor(void *ptr)
|
||||
{
|
||||
list_entry *le = (list_entry *) ptr;
|
||||
list_destructors_entry *ld;
|
||||
|
||||
if (zend_hash_index_find(&list_destructors,le->type,(void **) &ld)==SUCCESS) {
|
||||
if (ld->plist_destructor) {
|
||||
(ld->plist_destructor)(le->ptr);
|
||||
}
|
||||
} else {
|
||||
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)",le->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int init_resource_list(void)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0);
|
||||
}
|
||||
|
||||
|
||||
int init_resource_plist(void)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
return zend_hash_init(&EG(persistent_list), 0, NULL, plist_entry_destructor, 1);
|
||||
}
|
||||
|
||||
|
||||
void destroy_resource_list(void)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
zend_hash_destroy(&EG(regular_list));
|
||||
}
|
||||
|
||||
|
||||
void destroy_resource_plist(void)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
zend_hash_destroy(&EG(persistent_list));
|
||||
}
|
||||
|
||||
|
||||
static int clean_module_resource(list_entry *le, int *resource_id)
|
||||
{
|
||||
if (le->type == *resource_id) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int clean_module_resource_destructors(list_destructors_entry *ld, int *module_number)
|
||||
{
|
||||
if (ld->module_number == *module_number) {
|
||||
ELS_FETCH();
|
||||
|
||||
zend_hash_apply_with_argument(&EG(persistent_list), (int (*)(void *,void *)) clean_module_resource, (void *) &(ld->resource_id));
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
*/
|
||||
Loaded 100 of 2031 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user