Compare commits

..
Author SHA1 Message Date
George Schlossnagle ef4573eaf2 white space changes (s/ /\t/g) 2002-10-23 07:12:13 +00:00
George Schlossnagle c382dbbac6 fixed directory merging 2002-10-23 06:07:07 +00:00
George Schlossnagle d9647606fb fixed return values for php_response_handler 2002-10-09 02:57:33 +00:00
George Schlossnagle a4ec6e9fa1 headers code cleanup 2002-10-08 06:42:54 +00:00
George Schlossnagle 7adb8e0ba9 header code cleanup 2002-10-08 06:25:02 +00:00
George Schlossnagle b85162590d sync with head. add optional content type param to send_http_header 2002-10-08 02:17:02 +00:00
George Schlossnagle 868773aa3d sync with head 2002-10-08 02:16:25 +00:00
George Schlossnagle 2306fe934d Cleaned up a bunch of code, fully integrated the class::method handler
code into a single stack per handlers (for correct interleaving).

Changed the syntax so that now they are of the form

phpUriHandler /filename
phpUriHandlerMethod Class::Method

This now works for all handlers including response handlers.
2002-08-30 19:12:28 +00:00
George Schlossnagle b0e2b8604f added the ability to set handlers as class methods (classes will need to be
declared in a phpRequire statemenet, of course, or be otherwise available
at the hook run-time (builtins)).  This is currently only implemented
for the uri trans handler  it is usable as:

phpUriHandlerCodeRef MyClass::MyMethod

This can be greatly robustified from whre it stands now, but is a good proof
of concept (hopefully!)
2002-08-29 20:23:07 +00:00
George Schlossnagle d44619a811 added all the sub_request methods and logging methods 2002-08-28 21:23:12 +00:00
George Schlossnagle 2bc1d055cb Added wrapper functions for the majority of the apache API_EXPORT functions
as class methods for the ApacheRequest objects.  broke sapi_activate
into two functions to allow for reading of headers/cookies separately
from request bodies (POST stuff).  Altered some of the send_headers code
in mod_php4.c to prevent sending headers twice (since a phpResponseHandler
needs to be able to have full freedom for setting headers using the
ap_*_header* functions.
2002-08-28 18:56:51 +00:00
George Schlossnagle 0a105b4130 added wrapper for ap_send_http_header so that phpResponseHandler is now
working.  Added protections to mod_php4's internal call to the same so
that headers cannot be accidentally sent twice.
2002-08-28 04:37:37 +00:00
George Schlossnagle 22528c9e59 This handler works much better when not commented out. :) 2002-08-28 03:55:42 +00:00
George Schlossnagle 4030dc1224 All handlers are now 'stacked' allowing for multiple handlers to be called in the
order they are listed in the httpd.conf for a section.  phpRequire is now supported (called out of the post-read request handler), and a first attempt at phpResponseHandler, a response-time type handler which is set by a

<Location blah>
SetHandler php-script
phpResponseHandler /tmp/foo.php
</Location>

To allow for the stacked handlers, the entirety of zend_stack.c was imported into mod_php4.c.  There is a patch pending to zend_stack.c to add the functionality so that all the redundant code can be removed.
2002-08-27 20:57:09 +00:00
George Schlossnagle b185cac59d Replaced handler loading commands such that what was
php_value uri_handler /tmp/foo.php

is now

phpUriHandler	/tmp/foo.php

This fixes some bugs that caused handlers to be skipped or mysteriously 'unloaded',
reduces the number of calls to zend_alter_ini_entries that are necessary, as well
as allows for easier implementation of stacked handlers (which comes next).

Added 2 new hooks, phpPostReadHandler and phpHeaderHandler (going to the obvious places).
2002-08-27 14:41:53 +00:00
lukas schroeder dc0ad431c8 - add interface functions for headers_in, headers_out and err_headers_out 2002-08-26 23:49:15 +00:00
lukas schroeder f3f7b97826 - put common sapi startup code into a function 2002-08-26 23:14:21 +00:00
George Schlossnagle f05126e2cf Import of Lukas Schroeder's work to give php a full interface to apache 1.3.x's hook interface, and full class wrappers around the apache request object and it's interfaces. 2002-08-26 20:06:31 +00:00
George Schlossnagle ea996e0fa6 new full apache-1.3.x hooks interface support initial import 2002-08-26 20:02:18 +00:00
SVN Migration 025580f68a This commit was manufactured by cvs2svn to create branch 'apache_hooks'. 2002-08-22 07:56:40 +00:00
Rasmus Lerdorf 15611c1885 Ok, get it onto the right branch
(cvs can get annoying sometimes)
2001-09-06 23:39:02 +00:00
Rasmus Lerdorf 2797cf1323 Apache request handler hook framework. So far only the uri hook is
implemented, but the others will be easy once I finish the uri translation
example.  The big things left to do is to create a proper $r request
object to be manipulated in user-space and also to verify that the hooks
don't steal the POST data such that it isn't available to the content
handler once it is finally called.  Or if we do steal it, make sure it
is somehow available to the content handler later on.

Comments and help with this stuff is more than welcome.  Check out these
files from the 'apache_hooks' branch to play along.
2001-09-06 09:53:34 +00:00
SVN Migration 22f9e24408 This commit was manufactured by cvs2svn to create branch 'apache_hooks'. 2001-08-31 22:03:25 +00:00
2163 changed files with 2593 additions and 623615 deletions

No files matched your search

-285
View File
@@ -1,285 +0,0 @@
define dump_bt
set $t = $arg0
while $t
printf "[0x%08x] ", $t
if $t->function_state.function->common.function_name
printf "%s() ", $t->function_state.function->common.function_name
else
printf "??? "
end
if $t->op_array != 0
printf "%s:%d ", $t->op_array->filename, $t->opline->lineno
end
set $t = $t->prev_execute_data
printf "\n"
end
end
document dump_bt
dumps the current execution stack. usage: dump_bt executor_globals.current_execute_data
end
define printzv
set $ind = 0
____printzv $arg0 0
end
document printzv
prints content of zval
end
define ____printzv
set $zvalue = $arg0
if $zvalue->type == 0
set $typename = "NULL"
end
if $zvalue->type == 1
set $typename = "long"
end
if $zvalue->type == 2
set $typename = "double"
end
if $zvalue->type == 3
set $typename = "string"
end
if $zvalue->type == 4
set $typename = "array"
end
if $zvalue->type == 5
set $typename = "object"
end
if $zvalue->type == 6
set $typename = "bool"
end
if $zvalue->type == 7
set $typename = "resource"
end
if $zvalue->type == 8
set $typename = "constant"
end
if $zvalue->type == 9
set $typename = "const_array"
end
printf "[0x%08x] ", $zvalue
if $zvalue == executor_globals.uninitialized_zval_ptr
printf "*uninitialized* "
end
printf "(refcount=%d) %s: ", $zvalue->refcount, $typename
if $zvalue->type == 1
printf "%ld", $zvalue->value.lval
end
if $zvalue->type == 2
printf "%lf", $zvalue->value.dval
end
if $zvalue->type == 3
printf "\"%s\"(%d)", $zvalue->value.str.val, $zvalue->value.str.len
end
if $zvalue->type == 4
if ! $arg1
printf "{\n"
set $ind = $ind + 1
____print_ht $zvalue->value.ht
set $ind = $ind - 1
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
printf "}"
end
end
if $zvalue->type == 5
if ! $arg1
printf "(prop examination disabled due to a gdb bug)"
# set $ht = $zvalue->value.obj.handlers->get_properties($zvalue)
# printf "{\n"
# set $ind = $ind + 1
# ____print_ht $ht
# set $ind = $ind - 1
# set $i = $ind
# while $i > 0
# printf " "
# set $i = $i - 1
# end
# printf "}"
end
end
if $zvalue->type == 6
if $zvalue->lval
printf "true"
else
printf "false"
end
end
if $zvalue->type == 7
printf "#%d", $zvalue->value.lval
end
printf "\n"
end
define ____print_ht
set $ht = $arg0
set $p = $ht->pListHead
while $p != 0
set $zval = *(struct _zval_struct **)$p->pData
set $i = $ind
while $i > 0
printf " "
set $i = $i - 1
end
if $p->nKeyLength > 0
printf "\"%s\" => ", $p->arKey
else
printf "%d => ", $p->h
end
____printzv $zval 1
set $p = $p->pListNext
end
end
define print_ht
set $ind = 1
printf "[0x%08x] {\n", $arg0
____print_ht $arg0
printf "}\n"
end
document print_ht
dumps elements of HashTable made of zval
end
define printzn
set $ind = 0
set $znode = $arg0
if $znode->op_type == 1
set $optype = "IS_CONST"
end
if $znode->op_type == 2
set $optype = "IS_TMP_VAR"
end
if $znode->op_type == 4
set $optype = "IS_VAR"
end
if $znode->op_type == 8
set $optype = "IS_UNUSED"
end
printf "[0x%08x] %s", $znode, $optype
if $znode->op_type == 1
printf ": "
____printzv &$znode->u.constant
end
if $znode->op_type == 2
printf ": "
set $tvar = (union _temp_variable *)((char *)executor_globals.current_execute_data->Ts + $znode->u.var)
____printzv ((union _temp_variable *)$tvar)->tmp_var
end
if $znode->op_type == 4
printf ": "
set $tvar = (union _temp_variable *)((char *)executor_globals.current_execute_data->Ts + $znode->u.var)
____printzv *$tvar->var.ptr_ptr
end
if $znode->op_type == 8
printf "\n"
end
end
document printzn
print type and content of znode.
usage: printzn &opline->op1
end
define printzops
printf "op1 => "
printzn &execute_data->opline.op1
printf "op2 => "
printzn &execute_data->opline.op2
printf "result => "
printzn &execute_data->opline.result
end
document printzops
dump operands of the current opline
end
define zmemcheck
set $p = alloc_globals.head
set $stat = "?"
set $total_size = 0
if $arg0 != 0
set $not_found = 1
else
set $not_found = 0
end
printf " block size status file:line\n"
printf "-------------------------------------------------------------------------------\n"
while $p
set $aptr = $p + sizeof(struct _zend_mem_header) + sizeof(align_test)
if $arg0 == 0 || (void *)$aptr == (void *)$arg0
if $p->magic == 0x7312f8dc
set $stat = "OK"
end
if $p->magic == 0x99954317
set $stat = "FREED"
end
if $p->magic == 0xfb8277dc
set $stat = "CACHED"
end
set $filename = strrchr($p->filename, '/')
if !$filename
set $filename = $p->filename
else
set $filename = $filename + 1
end
printf " 0x%08x ", $aptr
if $p->size == sizeof(struct _zval_struct) && ((struct _zval_struct *)$aptr)->type >= 0 && ((struct _zval_struct *)$aptr)->type < 10
printf "ZVAL?(%-2d) ", $p->size
else
printf "%-9d ", $p->size
end
set $total_size = $total_size + $p->size
printf "%-06s %s:%d", $stat, $filename, $p->lineno
if $p->orig_filename
set $orig_filename = strrchr($p->orig_filename, '/')
if !$orig_filename
set $orig_filename = $p->orig_filename
else
set $orig_filename = $orig_filename + 1
end
printf " <= %s:%d\n", $orig_filename, $p->orig_lineno
else
printf "\n"
end
if $arg0 != 0
set $p = 0
set $not_found = 0
else
set $p = $p->pNext
end
else
set $p = $p->pNext
end
end
if $not_found
printf "no such block that begins at 0x%08x.\n", $aptr
end
if $arg0 == 0
printf "-------------------------------------------------------------------------------\n"
printf " total: %d bytes\n", $total_size
end
end
document zmemcheck
show status of a memory block.
usage: zmemcheck [ptr].
if ptr is 0, all blocks will be listed.
end
-294
View File
@@ -1,294 +0,0 @@
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.
Code Implementation
-------------------
[0] Document your code in source files and the manual. [tm]
[1] Functions that are given pointers to resources should not free them
For instance, function int mail(char *to, char *from) should NOT free
to and/or from.
Exceptions:
- The function's designated behavior is freeing that resource. E.g. efree()
- The function is given a boolean argument, that controls whether or not
the function may free its arguments (if true - the function must free its
arguments, if false - it must not)
- Low-level parser routines, that are tightly integrated with the token
cache and the bison code for minimum memory copying overhead.
[2] Functions that are tightly integrated with other functions within the
same module, and rely on each other non-trivial behavior, should be
documented as such and declared 'static'. They should be avoided if
possible.
[3] Use definitions and macros whenever possible, so that constants have
meaningful names and can be easily manipulated. The only exceptions
to this rule are 0 and 1, when used as false and true (respectively).
Any other use of a numeric constant to specify different behavior
or actions should be done through a #define.
[4] When writing functions that deal with strings, be sure to remember
that PHP holds the length property of each string, and that it
shouldn't be calculated with strlen(). Write your functions in a such
a way so that they'll take advantage of the length property, both
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())
[5] Use php_error_docref() group of functions to report any errors/warnings
during code execution. Use descriptive error messages, and try to avoid
using identical error strings for different stages of an error. For
example, if in order to obtain a URL you have to parse the URL, connect,
and retreive the text, assuming something can go wrong at each of these
stages, don't report an error "Unable to get URL" on all of them, but
instead, write something like "Unable to parse URL", "Unable to connect
to URL server" and "Unable to fetch URL text", respectively.
It has been silently agreed to prefix every php_error() message with the
name of the current function if applicable:
php_error(E_WHATEVER, "%s(): Desc.", get_active_function_name(TSRMLS_C));
This can be done automatically using php_error_docref(). The first
parameter, docref, is either NULL or the URL of a page describing the
error in detail. In most cases you will pass NULL, to generate the URL
from the name of the function being executed:
php_error_docref(NULL TSRMLS_CC, E_WHATEVER, "Desc.");
If you pass a URL, it can either be a full URL beginning with "http://":
php_error_docref("http://externalsite.tld/page.ext#error"
TSRMLS_CC, E_WHATEVER, "Desc.");
Or the name of a manual page without file extension, but with an optional
target anchor. Or simply the anchor within the manual page of the current
function. When using function names you must replace '_' by '-':
php_error_docref("function.ext-func#error" TSRMLS_CC, E_WHATEVER, "Desc.");
To display one or two important parameters after the function name, use
php_error_docref1() or php_error_docref2(). For example, file functions
should display the name of the file opened:
php_error_docref1("function.fopen" TSRMLS_CC, filename,
E_WHATEVER, "Desc.");
php_error_docref2("function.fopen" TSRMLS_CC, filename, openmode,
E_WHATEVER, "Desc.");
Fixing ("unifying") existing php_error() message is a good thing [tm].
[6] NEVER USE strncat(). If you're absolutely sure you know what you're doing,
check its man page again, and only then, consider using it, and even then,
try avoiding it.
[7] Use PHP_* macros in the PHP source, and ZEND_* macros in the Zend
part of the source. Although the PHP_* macro's are mostly aliased to the
ZEND_* macros it gives a better understanding on what kind of macro you're
calling.
[8] Use assert(). assert.h is included in php.h if it is available. Not only
does good assertion catch bugs, but it also helps with code readability.
- Do not use assert for error handling. Use assert only for the
condition that must be always true.
- Do not use assignments in assert conditions. If you assign inside an
assert condition, you risk an elusive bug that would be very difficult
to spot in a debug build, due to the side effect of the assignment.
Function calls in assert conditions may also cause this problem, if
they modify one of their arguments or global variables.
[9] When commenting out code using a #if statement, do NOT use 0 only. Instead
use "<cvs username here>_0". For example, #if FOO_0, where FOO is your
cvs user foo. This allows easier tracking of why code was commented out,
especially in bundled libraries.
[10] Do not define functions that are not available. For instance, if a
library is missing a function, do not define the PHP version of the
function, and do not raise a run-time error about the function not
existing. End users should use function_exists() to test for the
existence of a function
[11] Prefer emalloc(), efree(), estrdup(), etc. to their standard C library
counterparts. These functions implement an internal "safety-net"
mechanism that ensures the deallocation of any unfreed memory at the
end of a request. They also provide useful allocation and overflow
information while running in debug mode.
In almost all cases, memory returned to the engine must be allocated
using emalloc().
The use of malloc() should be limited to cases where a third-party
library may need to control or free the memory, or when the memory in
question needs to survive between multiple requests.
Naming Conventions
------------------
[1] Function names for user-level functions should be enclosed with in
the PHP_FUNCTION() macro. They should be in lowercase, with words
underscore delimited, with care taken to minimize the letter count.
Abbreviations should not be used when they greatly decrease the
readability of the function name itself.
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
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
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
between words.
Syntax and indentation
----------------------
[1] Never use C++ style comments (i.e. // comment). Always use C-style
comments instead. PHP is written in C, and is aimed at compiling
under any ANSI-C compliant compiler. Even though many compilers
accept C++-style comments in C code, you have to ensure that your
code would compile with other compilers as well.
The only exception to this rule is code that is Win32-specific,
because the Win32 port is MS-Visual C++ specific, and this compiler
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,
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
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) {
bar;
}
to:
if(foo)bar;
Keep one empty line between the variable declaration 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
-------------------------------
In order to make sure that the online documentation stays in line with
the code, each user-level function should have its user-level function
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)
{
...
}
/* }}} */
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.
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
function prototypes allows us to put folds elsewhere in the code without
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.
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.
-2
View File
@@ -1,2 +0,0 @@
For the list of people who've put work into PHP, please see
http://www.php.net/credits.php
-34690
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-507
View File
@@ -1,507 +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: activescript
PRIMARY MAINTAINER: Wez Furlong <wez@php.net>
MAINTENANCE: Odd Fixes
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: apache
PRIMARY MAINTAINER: Rasmus Lerdorf <rasmus@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: apache2
PRIMARY MAINTAINER: Aaron Bannert <aaron@php.net>
MAINTENANCE: Maintained
STATUS: Experimental
-------------------------------------------------------------------------------
EXTENSION: cgi
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: cli
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: fhttpd
MAINTENANCE: Unknown
STATUS: Unknown
-------------------------------------------------------------------------------
EXTENSION: isapi
MAINTENANCE: Unknown
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: nsapi
PRIMARY MAINTAINER: Uwe Schindler <thetaphi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
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: Marcus Börger <helly@php.net>
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>, Ard Biesheuvel <ard@ard.nu>
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
PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>
MAINTENANCE: Maintained
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
-------------------------------------------------------------------------------
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: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.3
-------------------------------------------------------------------------------
EXTENSION: dio
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
EXTENSION: cyrus
PRIMARY MAINTAINER: Sterling Hughes <sterling@php.net>
MAINTENANCE: Orphaned
STATUS: Working
SINCE: 4.0.6
-------------------------------------------------------------------------------
EXTENSION: calendar
PRIMARY MAINTAINER: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
-------------------------------------------------------------------------------
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: fribidi
PRIMARY MAINTAINER: Tal Peer <tal@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
EXTENSION: ftp
PRIMARY MAINTAINER: Stefan Esser (sesser@php.net)
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
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: iconv
PRIMARY MAINTAINER: Moriyoshi Koizumi <moriyoshi@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
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: Orphaned
STATUS: Deprecated (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: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working (mostly)
-------------------------------------------------------------------------------
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: Hartmut Holzgraefe <hartmut@six.de>
MAINTENANCE: Odd Fixes
STATUS: Working
SINCE: 4.0.5
-------------------------------------------------------------------------------
# iptc?
-422
View File
@@ -1,422 +0,0 @@
Installation Instructions for PHP 4
-----------------------------------
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
For Apache 2, instructions and up-to-date information regarding it's
support status, is available here:
http://www.php.net/manual/en/install.apache2.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
QUICK INSTALL (DSO)
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
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.
Edit your httpd.conf or srm.conf file and add:
AddType application/x-httpd-php .php
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:
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
Next you have to untar it with: tar -xvf php-4.x.y.tar
This will create a php-4.x.y directory. cd into this new directory.
2a. Configure PHP (Dynamic Module) - Skip to 2b if you wish to build
a static module
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
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. You need
to know where the source code directory for your Apache server is
located. Then use an option like: --with-apache=/usr/local/src/apache
if that is your Apache source code directory. If you only specify
--with-apache, then it will default to look for your Apache source
in /usr/local/etc/httpd.
NOTE: The directory you specify should be the top-level of the
unpacked Apache (or Stronghold) distribution. The configure program
will automatically look for httpd.h in different directories under that
location depending on which version of Apache, including Stronghold,
you are running.
For MySQL support, since newer versions of MySQL installs its various
components under /usr/local, this is the default. If you have
changed the location you can specify it with: --with-mysql=/opt/local
for example. Otherwise just use: --with-mysql
*NOTE* If you are using Apache 1.3b6 or later, you should run the
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
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.
For Apache 1.3b6 and later, you can use the new APACI configuration
mechanism. To automatically build Apache with PHP support, use:
cd apache_1.3.x
./configure --prefix=/<path>/apache \
--activate-module=src/modules/php4/libphp4.a
make
make install
If you do not wish to use this new configuration tool, the old
install procedure (src/Configure) will work fine.
If you are using the old Apache ./Configure script, you will have to
edit the Apache src/Configuration file manually. If you do not have
this file, copy Configuration.tmpl to Configuration.
For Apache 1.3.x add:
AddModule modules/php4/libphp4.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
For Apache 1.2.x you will also have to look in the libphp4.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
"-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
NOTE: You should not enclose the EXTRA_LIBS line in double-quotes, as it
is in the libphp4.module file.
Also, look at the RULE_WANTHSREGEX setting in the libphp4.module file
and set the WANTHSREGEX directive accordingly in your Configuration file.
This last step applies to versions of Apache prior to 1.3b3.
This is a bit of a hassle, but should serve as incentive to move to
Apache 1.3.x where this step has been eliminated.
Once you are satisfied with your Configuration settings, type: ./Configure
If you get errors, chances are that you forgot a library or made a typo
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)
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
and add the line:
AddType application/x-httpd-php .php
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
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
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 \
-68
View File
@@ -1,68 +0,0 @@
--------------------------------------------------------------------
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.
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.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP, freely available from
<http://www.php.net/>".
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 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>.
-23
View File
@@ -1,23 +0,0 @@
#
# Zend
#
$(builddir)/zend_language_scanner.lo: $(builddir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(builddir)/zend_ini_parser.h
$(builddir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
$(builddir)/zend_language_parser.h: $(builddir)/zend_language_parser.c
$(builddir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@
$(builddir)/zend_ini_parser.h: $(builddir)/zend_ini_parser.c
$(builddir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
$(builddir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(builddir)/zend_language_parser.h
-78
View File
@@ -1,78 +0,0 @@
mkinstalldirs = $(top_srcdir)/build/shtool mkdir -p
INSTALL = $(top_srcdir)/build/shtool install -c
INSTALL_DATA = $(INSTALL) -m 644
DEFS = -DPHP_ATOM_INC -I$(top_builddir)/include -I$(top_builddir)/main -I$(top_srcdir)
COMMON_FLAGS = $(DEFS) $(INCLUDES) $(EXTRA_INCLUDES) $(CPPFLAGS) $(PHP_FRAMEWORKPATH)
all: $(all_targets)
@echo
@echo "Build complete."
@echo "(It is safe to ignore warnings about tempnam and tmpnam)."
@echo
build-modules: $(PHP_MODULES)
libphp4.la: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
-@$(LIBTOOL) --silent --mode=install cp libphp4.la $(phptempdir)/libphp4.la >/dev/null 2>&1
libs/libphp4.bundle: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(CC) $(MH_BUNDLE_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_SAPI_OBJS:.lo=.o) $(PHP_FRAMEWORKS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@ && cp $@ libs/libphp4.so
install: $(all_targets) $(install_targets)
install-sapi: $(OVERALL_TARGET)
@echo "Installing PHP SAPI module: $(PHP_SAPI)"
-@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir)
-@if test ! -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); then \
for i in 0.0.0 0.0 0; do \
if test -r $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i; then \
$(LN_S) $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME).$$i $(phptempdir)/libphp4.$(SHLIB_SUFFIX_NAME); \
break; \
fi; \
done; \
fi
@$(INSTALL_IT)
install-modules: build-modules
@test -d modules && \
$(mkinstalldirs) $(INSTALL_ROOT)$(EXTENSION_DIR) && \
echo "Installing shared extensions: $(INSTALL_ROOT)$(EXTENSION_DIR)/" && \
rm -f modules/*.la && \
$(INSTALL) modules/* $(INSTALL_ROOT)$(EXTENSION_DIR) >/dev/null 2>&1 || true
install-tester:
@echo "Installing regression tester: $(INSTALL_ROOT)$(PEAR_INSTALLDIR)/"
@$(mkinstalldirs) $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
@$(INSTALL) -m 755 $(top_srcdir)/run-tests.php $(INSTALL_ROOT)$(PEAR_INSTALLDIR)
install-su: install-pear install-tester
test:
-@if test -x $(SAPI_CLI_PATH) && test ! -z $(SAPI_CLI_PATH); then \
TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(top_builddir)/$(SAPI_CLI_PATH) -d 'open_basedir=' -d 'safe_mode=0' -d 'output_buffering=0' $(top_srcdir)/run-tests.php $(TESTS); \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
clean:
find . -name \*.lo | xargs rm -f
find . -name \*.o | xargs rm -f
find . -name \*.la | xargs rm -f
find . -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp4.la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
distclean: clean
rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php4.spec sapi/apache/libphp4.module buildmk.stamp
egrep define'.*include/php' configure|sed 's/.*>//'|xargs rm -f
find . -name Makefile | xargs rm -f
.PHONY: all clean install distclean test
.NOEXPORT:
-2874
View File
File diff suppressed because it is too large. Load diff
-115
View File
@@ -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
-39
View File
@@ -1,39 +0,0 @@
Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way
that broke both source and binary compatibility. If you are
maintaining a third party extension, here's how to update it:
If this was your old module entry:
zend_module_entry foo_module_entry = {
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
STANDARD_MODULE_PROPERTIES
};
Here's how it should look if you want your code to build with PHP
4.1.0 and up:
zend_module_entry foo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"foo", /* extension name */
foo_functions, /* extension function list */
NULL, /* extension-wide startup function */
NULL, /* extension-wide shutdown function */
PHP_RINIT(foo), /* per-request startup function */
PHP_RSHUTDOWN(foo), /* per-request shutdown function */
PHP_MINFO(foo), /* information function */
#if ZEND_MODULE_API_NO >= 20010901
FOO_VERSION, /* extension version number (string) */
#endif
STANDARD_MODULE_PROPERTIES
};
If you don't care about source compatibility with earlier PHP releases
than 4.1.0, you can drop the #if/#endif lines.
-189
View File
@@ -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, change to the ext/ directory of the PHP 4 sources. If
you just need the basic framework and will be writing all the code in your
functions yourself, you can now do
./ext_skel --extname=module_name
and everything you need is placed in directory module_name.
[ Note that GNU awk is likely required for this script to work. Debian
systems seem to default to using mawk, so you may need to change the
#! line in skeleton/create_stubs to use gawk explicitly. ]
If you don't need to test the existence of any external header files,
libraries or functions in them, the module is already almost ready to be
compiled in PHP. Just remove 3 comments in your_module_name/config.m4,
change back up to PHP sources top directory, and do
./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, e.g.
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");
}
/* }}} */
-127
View File
@@ -1,127 +0,0 @@
New parameter parsing functions
===============================
It should be easier to parse input parameters to an extension function.
Hence, borrowing from Python's example, there are now a set of functions
that given the string of type specifiers, can parse the input parameters
and store the results in the user specified variables. This avoids most
of the IS_* checks and convert_to_* conversions. The functions also
check for the appropriate number of parameters, and try to output
meaningful error messages.
Prototypes
----------
/* Implemented. */
int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...);
int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...);
The zend_parse_parameters() function takes the number of parameters
passed to the extension function, the type specifier string, and the
list of pointers to variables to store the results in. The _ex() version
also takes 'flags' argument -- current only ZEND_PARSE_PARAMS_QUIET can
be used as 'flags' to specify that the function should operate quietly
and not output any error messages.
Both functions return SUCCESS or FAILURE depending on the result.
The auto-conversions are performed as necessary. Arrays, objects, and
resources cannot be auto-converted.
Type specifiers
---------------
l - long
d - double
s - string (with possible null bytes) and its length
b - boolean, stored in zend_bool
r - resource (stored in zval)
a - array
o - object (of any type)
O - object (of specific type, specified by class entry)
z - the actual zval
The following characters also have a meaning in the specifier string:
| - indicates that the remaining parameters are optional, they
should be initialized to default values by the extension since they
will not be touched by the parsing function if they are not
passed to it.
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
! - the parameter it follows can be of specified type or NULL (only applies
to 'a', 'o', 'O', 'r', and 'z'). If NULL is passed, the results
pointer is set to NULL as well.
Examples
--------
/* Gets a long, a string and its length, and a zval */
long l;
char *s;
int s_len;
zval *param;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsz",
&l, &s, &s_len, &param) == FAILURE) {
return;
}
/* Gets an object of class specified by my_ce, and an optional double. */
zval *obj;
double d = 0.5;
zend_class_entry my_ce;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|d",
&obj, my_ce, &d) == FAILURE) {
return;
}
/* Gets an object or null, and an array.
If null is passed for object, obj will be set to NULL. */
zval *obj;
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a",
&obj, &arr) == FAILURE) {
return;
}
/* Gets a separated array which can also be null. */
zval *arr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/!",
&arr) == FAILURE) {
return;
}
/* Get only the first three parameters (useful for varargs functions). */
zval *z;
zend_bool b;
zval *r;
if (zend_parse_parameters(3 TSRMLS_CC, "zbr!",
&z, &b, &r) == FAILURE) {
return;
}
/* Get either a set of 3 longs or a string. */
long l1, l2, l3;
char *s;
/*
* The function expects a pointer to a integer in this case, not a long
* or any other type. If you specify a type which is larger
* than a 'int', the upper bits might not be initialized
* properly, leading to random crashes on platforms like
* Tru64 or Linux/Alpha.
*/
int length;
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"lll", &l1, &l2, &l3) == SUCCESS) {
/* manipulate longs */
} else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"s", &s, &length) == SUCCESS) {
/* manipulate string */
} else {
/* output error */
return;
}
-57
View File
@@ -1,57 +0,0 @@
QNX4 Installation Notes
-----------------------
NOTE: General installation instructions are in the INSTALL file
1. To compile and test PHP3 you have to grab, compile and install:
- GNU dbm library or another db library;
- GNU bison (1.25 or later; 1.25 tested);
- GNU flex (any version supporting -o and -P options; 2.5.4 tested);
- GNU diffutils (any version supporting -w option; 2.7 tested);
2. To use CVS version you may need also:
- GNU CVS (1.9 tested);
- GNU autoconf (2.12 tested);
- GNU m4 (1.3 or later preferable; 1.4 tested);
3. To run configure define -lunix in command line:
LDFLAGS=-lunix ./configure
4. To use Sybase SQL Anywhere define ODBC_QNX and CUSTOM_ODBC_LIBS in
command line and run configure with --with-custom-odbc:
CFLAGS=-DODBC_QNX LDFLAGS=-lunix CUSTOM_ODBC_LIBS="-ldblib -lodbc" ./configure --with-custom-odbc=/usr/lib/sqlany50
If you have SQL Anywhere version 5.5.00, then you have to add
CFLAGS=-DSQLANY_BUG
to workaround its SQLFreeEnv() bug. Other versions has not been tested,
so try without this flag first.
5. To build the Apache module, you may have to hardcode an include path for
alloc.h in your Apache base directory:
- APACHE_DIRECTORY/src/httpd.h:
change #include "alloc.h"
to #include "APACHE_DIRECTORY/src/alloc.h"
Unless you want to use system regex library, you have to hardcode also
a path to regex.h:
- APACHE_DIRECTORY/src/conf.h:
change #include <regex.h>
to #include "APACHE_DIRECTORY/src/regex/regex.h"
I don't know so far why this required for QNX, may be it is Watcom
compiler problem.
If you building Apache module with SQL Anywhere support, you'll get
symbol conflict with BOOL. It is defined in Apache (httpd.h) and in
SQL Anywhere (odbc.h). This has nothing to do with PHP, so you have to
fix it yourself someway.
6. With above precautions, it should compile as is and pass regression
tests completely:
make
make check
make install
Don't bother me unless you really sure you made that all but it
still doesn't work.
June 28, 1998
Igor Kovalenko -- owl@infomarket.ru
-155
View File
@@ -1,155 +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, two 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. Then, run phpize
(this is installed during make install by PHP 4.0).
For example, if you configured PHP with --prefix=/php, you would run
$ /php/bin/phpize
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
-373
View File
@@ -1,373 +0,0 @@
An Overview of the PHP Streams abstraction
==========================================
$Id$
WARNING: some prototypes in this file are out of date.
The information contained here is being integrated into
the PHP manual - stay tuned...
Please send comments to: Wez Furlong <wez@thebrainroom.com>
Why Streams?
============
You may have noticed a shed-load of issock parameters flying around the PHP
code; we don't want them - they are ugly and cumbersome and force you to
special case sockets and files every time you need to work with a "user-level"
PHP file pointer.
Streams take care of that and present the PHP extension coder with an ANSI
stdio-alike API that looks much nicer and can be extended to support non file
based data sources.
Using Streams
=============
Streams use a php_stream* parameter just as ANSI stdio (fread etc.) use a
FILE* parameter.
The main functions are:
PHPAPI size_t php_stream_read(php_stream * stream, char * buf, size_t count);
PHPAPI size_t php_stream_write(php_stream * stream, const char * buf, size_t
count);
PHPAPI size_t php_stream_printf(php_stream * stream TSRMLS_DC,
const char * fmt, ...);
PHPAPI int php_stream_eof(php_stream * stream);
PHPAPI int php_stream_getc(php_stream * stream);
PHPAPI char *php_stream_gets(php_stream * stream, char *buf, size_t maxlen);
PHPAPI int php_stream_close(php_stream * stream);
PHPAPI int php_stream_flush(php_stream * stream);
PHPAPI int php_stream_seek(php_stream * stream, off_t offset, int whence);
PHPAPI off_t php_stream_tell(php_stream * stream);
These (should) behave in the same way as the ANSI stdio functions with similar
names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell.
Opening Streams
===============
In most cases, you should use this API:
PHPAPI php_stream *php_stream_open_wrapper(char *path, char *mode,
int options, char **opened_path TSRMLS_DC);
Where:
path is the file or resource to open.
mode is the stdio compatible mode eg: "wb", "rb" etc.
options is a combination of the following values:
IGNORE_PATH (default) - don't use include path to search for the file
USE_PATH - use include path to search for the file
IGNORE_URL - do not use plugin wrappers
REPORT_ERRORS - show errors in a standard format if something
goes wrong.
STREAM_MUST_SEEK - If you really need to be able to seek the stream
and don't need to be able to write to the original
file/URL, use this option to arrange for the stream
to be copied (if needed) into a stream that can
be seek()ed.
opened_path is used to return the path of the actual file opened,
but if you used STREAM_MUST_SEEK, may not be valid. You are
responsible for efree()ing opened_path. opened_path may be (and usually
is) NULL.
If you need to open a specific stream, or convert standard resources into
streams there are a range of functions to do this defined in php_streams.h.
A brief list of the most commonly used functions:
PHPAPI php_stream *php_stream_fopen_from_file(FILE *file, const char *mode);
Convert a FILE * into a stream.
PHPAPI php_stream *php_stream_fopen_tmpfile(void);
Open a FILE * with tmpfile() and convert into a stream.
PHPAPI php_stream *php_stream_fopen_temporary_file(const char *dir,
const char *pfx, char **opened_path TSRMLS_DC);
Generate a temporary file name and open it.
There are some network enabled relatives in php_network.h:
PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
Convert a socket into a stream.
PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, int timeout, int persistent);
Open a connection to a host and return a stream.
PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
struct timeval *timeout);
Open a UNIX domain socket.
Stream Utilities
================
If you need to copy some data from one stream to another, you will be please
to know that the streams API provides a standard way to do this:
PHPAPI size_t php_stream_copy_to_stream(php_stream *src,
php_stream *dest, size_t maxlen);
If you want to copy all remaining data from the src stream, pass
PHP_STREAM_COPY_ALL as the maxlen parameter, otherwise maxlen indicates the
number of bytes to copy.
This function will try to use mmap where available to make the copying more
efficient.
If you want to read the contents of a stream into an allocated memory buffer,
you should use:
PHPAPI size_t php_stream_copy_to_mem(php_stream *src, char **buf,
size_t maxlen, int persistent);
This function will set buf to the address of the buffer that it allocated,
which will be maxlen bytes in length, or will be the entire length of the
data remaining on the stream if you set maxlen to PHP_STREAM_COPY_ALL.
The buffer is allocated using pemalloc(); you need to call pefree() to
release the memory when you are done.
As with copy_to_stream, this function will try use mmap where it can.
If you have an existing stream and need to be able to seek() it, you
can use this function to copy the contents into a new stream that can
be seek()ed:
PHPAPI int php_stream_make_seekable(php_stream *origstream, php_stream **newstream);
It returns one of the following values:
#define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */
#define PHP_STREAM_RELEASED 1 /* newstream should be used; origstream is no longer valid */
#define PHP_STREAM_FAILED 2 /* an error occurred while attempting conversion */
#define PHP_STREAM_CRITICAL 3 /* an error occurred; origstream is in an unknown state; you should close origstream */
make_seekable will always set newstream to be the stream that is valid
if the function succeeds.
When you have finished, remember to close the stream.
NOTE: If you only need to seek forward, there is no need to call this
function, as the php_stream_seek can emulate forward seeking when the
whence parameter is SEEK_CUR.
NOTE: Writing to the stream may not affect the original source, so it
only makes sense to use this for read-only use.
NOTE: If the origstream is network based, this function will block
until the whole contents have been downloaded.
NOTE: Never call this function with an origstream that is referenced
as a resource! It will close the origstream on success, and this
can lead to a crash when the resource is later used/released.
NOTE: If you are opening a stream and need it to be seekable, use the
STREAM_MUST_SEEK option to php_stream_open_wrapper();
Casting Streams
===============
What if your extension needs to access the FILE* of a user level file pointer?
You need to "cast" the stream into a FILE*, and this is how you do it:
FILE * fp;
php_stream * stream; /* already opened */
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void*)&fp, REPORT_ERRORS) == FAILURE) {
RETURN_FALSE;
}
The prototype is:
PHPAPI int php_stream_cast(php_stream * stream, int castas, void ** ret, int
show_err);
The show_err parameter, if non-zero, will cause the function to display an
appropriate error message of type E_WARNING if the cast fails.
castas can be one of the following values:
PHP_STREAM_AS_STDIO - a stdio FILE*
PHP_STREAM_AS_FD - a generic file descriptor
PHP_STREAM_AS_SOCKETD - a socket descriptor
If you ask a socket stream for a FILE*, the abstraction will use fdopen to
create it for you. Be warned that doing so may cause buffered data to be lost
if you mix ANSI stdio calls on the FILE* with php stream calls on the stream.
If your system has the fopencookie function, php streams can synthesize a
FILE* on top of any stream, which is useful for SSL sockets, memory based
streams, data base streams etc. etc.
In situations where this is not desirable, you should query the stream
to see if it naturally supports FILE *. You can use this code snippet
for this purpose:
if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
/* can safely cast to FILE* with no adverse side effects */
}
You can use:
PHPAPI int php_stream_can_cast(php_stream * stream, int castas)
to find out if a stream can be cast, without actually performing the cast, so
to check if a stream is a socket you might use:
if (php_stream_can_cast(stream, PHP_STREAM_AS_SOCKETD) == SUCCESS) {
/* it can be a socket */
}
Please note the difference between php_stream_is and php_stream_can_cast;
stream_is tells you if the stream is a particular type of stream, whereas
can_cast tells you if the stream can be forced into the form you request.
The former doesn't change anything, while the later *might* change some
state in the stream.
Stream Internals
================
There are two main structures associated with a stream - the php_stream
itself, which holds some state information (and possibly a buffer) and a
php_stream_ops structure, which holds the "virtual method table" for the
underlying implementation.
The php_streams ops struct consists of pointers to methods that implement
read, write, close, flush, seek, gets and cast operations. Of these, an
implementation need only implement write, read, close and flush. The gets
method is intended to be used for streams if there is an underlying method
that can efficiently behave as fgets. The ops struct also contains a label
for the implementation that will be used when printing error messages - the
stdio implementation has a label of "STDIO" for example.
The idea is that a stream implementation defines a php_stream_ops struct, and
associates it with a php_stream using php_stream_alloc.
As an example, the php_stream_fopen() function looks like this:
PHPAPI php_stream * php_stream_fopen(const char * filename, const char * mode)
{
FILE * fp = fopen(filename, mode);
php_stream * ret;
if (fp) {
ret = php_stream_alloc(&php_stream_stdio_ops, fp, 0, 0, mode);
if (ret)
return ret;
fclose(fp);
}
return NULL;
}
php_stream_stdio_ops is a php_stream_ops structure that can be used to handle
FILE* based streams.
A socket based stream would use code similar to that above to create a stream
to be passed back to fopen_wrapper (or it's yet to be implemented successor).
The prototype for php_stream_alloc is this:
PHPAPI php_stream * php_stream_alloc(php_stream_ops * ops, void * abstract,
size_t bufsize, int persistent, const char * mode)
ops is a pointer to the implementation,
abstract holds implementation specific data that is relevant to this instance
of the stream,
bufsize is the size of the buffer to use - if 0, then buffering at the stream
level will be disabled (recommended for underlying sources that implement
their own buffering - such a FILE*),
persistent controls how the memory is to be allocated - persistently so that
it lasts across requests, or non-persistently so that it is freed at the end
of a request (it uses pemalloc),
mode is the stdio-like mode of operation - php streams places no real meaning
in the mode parameter, except that it checks for a 'w' in the string when
attempting to write (this may change).
The mode parameter is passed on to fdopen/fopencookie when the stream is cast
into a FILE*, so it should be compatible with the mode parameter of fopen().
Writing your own stream implementation
======================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #1: when writing your own streams: make sure you have configured PHP with
--enable-debug.
I've taken some great pains to hook into the Zend memory manager to help track
down allocation problems. It will also help you spot incorrect use of the
STREAMS_DC, STREAMS_CC and the semi-private STREAMS_REL_CC macros for function
definitions.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RULE #2: Please use the stdio stream as a reference; it will help you
understand the semantics of the stream operations, and it will always
be more up to date than these docs :-)
First, you need to figure out what data you need to associate with the
php_stream. For example, you might need a pointer to some memory for memory
based streams, or if you were making a stream to read data from an RDBMS like
MySQL, you might want to store the connection and rowset handles.
The stream has a field called abstract that you can use to hold this data.
If you need to store more than a single field of data, define a structure to
hold it, allocate it (use pemalloc with the persistent flag set
appropriately), and use the abstract pointer to refer to it.
For structured state you might have this:
struct my_state {
MYSQL conn;
MYSQL_RES * result;
};
struct my_state * state = pemalloc(sizeof(struct my_state), persistent);
/* initialize the connection, and run a query, using the fields in state to
* hold the results */
state->result = mysql_use_result(&state->conn);
/* now allocate the stream itself */
stream = php_stream_alloc(&my_ops, state, 0, persistent, "r");
/* now stream->abstract == state */
Once you have that part figured out, you can write your implementation and
define the your own php_stream_ops struct (we called it my_ops in the above
example).
For example, for reading from this weird MySQL stream:
static size_t php_mysqlop_read(php_stream * stream, char * buf, size_t count)
{
struct my_state * state = (struct my_state*)stream->abstract;
if (buf == NULL && count == 0) {
/* in this special case, php_streams is asking if we have reached the
* end of file */
if (... at end of file ...)
return EOF;
else
return 0;
}
/* pull out some data from the stream and put it in buf */
... mysql_fetch_row(state->result) ...
/* we could do something strange, like format the data as XML here,
and place that in the buf, but that brings in some complexities,
such as coping with a buffer size too small to hold the data,
so I won't even go in to how to do that here */
}
Implement the other operations - remember that write, read, close and flush
are all mandatory. The rest are optional. Declare your stream ops struct:
php_stream_ops my_ops = {
php_mysqlop_write, php_mysqlop_read, php_mysqlop_close,
php_mysqlop_flush, NULL, NULL, NULL,
"Strange MySQL example"
}
Thats it!
Take a look at the STDIO implementation in streams.c for more information
about how these operations work.
The main thing to remember is that in your close operation you need to release
and free the resources you allocated for the abstract field. In the case of
the example above, you need to use mysql_free_result on the rowset, close the
connection and then use pefree to dispose of the struct you allocated.
You may read the stream->persistent field to determine if your struct was
allocated in persistent mode or not.
vim:tw=78:et
-127
View File
@@ -1,127 +0,0 @@
Submitting Patch for PHP
========================
This document describes how to submit a patch for PHP. Since you are
reading this document, you are willing to submit a patch for PHP.
Please keep reading! Submitting a patch for PHP is easy. The hard
part is making it acceptable for inclusion into our repository. :-)
How to create patch?
--------------------
We are working with CVS. You need to get CVS source to create a patch
that we accept. Visit http://www.php.net/anoncvs.php to get CVS
source. You can check out older versions, but make sure you get
the default branch (i.e. Do not use -r option when you check out the
CVS source)
Read CODING_STANDARDS file before you start working.
Now you are ready to create a patch. Modify source to fix a bug in PHP or
add a new feature to PHP. After you finished editing, please test your
patch. Read README.TESTING for testing.
After you finish testing your patch, take diff file using
"cvs diff > your.patch" command.
Read README.TESTING for submitting a test script for your patch. This is
not strictly required, but it is preferred to submit a test script along
with your patch. Making new test script is very easy. It also helps us
to understand what you have been fixed or added to PHP.
Tips for creating patch
-----------------------
If you would like to fix multiple bugs. It is easier for us if you
could create 1 patch for 1 bug, but this is not strictly required.
Note though that you might get little response, if your patch is
too hard to review.
If you would like change/add many lines, it is better to ask module
maintainer and/or internals@lists.php.net, or pear-dev@lists.php.net if
you are patching PEAR. Official module maintainers can be found in
EXTENSIONS file in PHP source.
If you are new to CVS (Concurrent Versions System), visit
http://cvshome.org/ for details.
Recommended CVS client settings for creating patch file
------------------------------------------------------
Recommended ~/.cvsrc file setting is:
------
cvs -z3
update -d -P
checkout -P
diff -u
------
diff -u means:
-u Use the unified output format.
With this CVS setting, you don't have to worry about adding/deleting
newlines and spaces.
Check list for submitting patch
-------------------------------
- Did you run "make test" to check if your patch didn't break
other features?
- Did you compile PHP with --enable-debug and check the PHP and
web server error logs when you test your patch?
- Did you build PHP for multi-threaded web servers. (Optional)
- Did you create test script for "make test"? (Recommended)
- Did you check your patch is unified format and it does not
contain white space changes? (If you are not using recommended
cvs setting)
- Did you update CVS source before you take final patch?
- Did you read the patch again?
Where to send your patch?
-------------------------
If you are patching C source, send the patch to internals@lists.php.net.
If you are patching a module, you should also send the patch to the
maintainer. Official module maintainers are listed in EXTENSION file
in source.
If you are patching PEAR, send the patch to pear-dev@lists.php.net.
Please add the prefix "[PATCH]" to your email subject and make sure
to include the patch as a MIME attachment even if it is short.
NOTE: only MIME attachments of type 'text/*' are accepted. The
easiest way to acclomplish this, is to make the extension
'.txt'.
Test scripts should be included in the same email.
Explain what has been fixed/added/changed by your patch.
Finally, add the bug Id(s) which can be closed by your patch, if any.
What happens after you submit your patch
--------------------------------------
If your patch is easy to review and has obviously no side-effects,
it might take up to a few hours until someone commits it.
Because this is a volunteer-driven effort, more complex patches will
require more patience on your side.
If you did not receive any feedback in a few days, please consider
resubmitting the description of your patch, along-side with
these questions:
- Is my patch too hard to review? Because of which factors?
- Should I split it up in multiple parts?
- Are there any unwanted whitespace changes?
What happens when your patch is applied?
----------------------------------------
Your name will be included together with your email address in the CVS
commit log. If your patch affects end-users, a brief description
and your name might be added to the NEWS file.
Thank you for submitting patch for PHP!
-307
View File
@@ -1,307 +0,0 @@
[IMPORTANT NOTICE]
------------------
Do _not_ ask to developers why some or all tests are failed under
your environment! Let us know if you find why it fails. Thank you.
[Testing Basics]
----------------
To execute test scripts, you must build PHP with some SAPI, then you
type "make test" to execute all or some test scripts saved under
"tests" directory under source root directory.
Usage:
make test
"make test" basically executes "run-tests.php" script
under the source root (parallel builds will not work). Therefore you
can execute the script as follows:
TEST_PHP_EXECUTABLE=sapi/cli/php \
sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
[Which "php" executable "make test" look for]
---------------------------------------------
You must use TEST_PHP_EXECUTABLE environment variable to explicitly
select the php executable to be used to run the tests. That can either
be the CLI or CGI executable.
"make test" executes "run-tests.php" script with "php" binary. Some
test scripts such as session must be executed by CGI SAPI. Therefore,
you must build PHP with CGI SAPI to perform all tests.
NOTE: PHP binary executing "run-tests.php" and php binary used for
executing test scripts may differ. If you use different PHP binary for
executing "run-tests.php" script, you may get errors.
[Which php.ini is used]
-----------------------
"make test" uses the same php.ini file as it would once installed.
The tests have been written to be independent of that php.ini file,
so if you find a test that is affected by a setting, please report
this, so we can address the issue.
[Which test scripts are executed]
---------------------------------
"run-tests.php" ("make test"), without any arguments executes all
test scripts by extracting all directories named "tests"
from the source root and any subdirectories below. If there are files,
which have a "phpt" extension, "run-tests.php" looks at the sections
in these files, determines whether it should run it, by evaluating
the 'SKIP' section. If the test is eligible for execution, the 'FILE'
section is extracted into a ".php" file (with the same name besides
the extension) and gets executed.
When an argument is given or TESTS environment variable is set, the
GLOB is expanded by the shell and any file with extension "*.phpt" is
regarded as a test file.
Tester can easily execute tests selectively with as follows.
Examples:
./sapi/cli/php run-tests.php ext/mbstring/*
./sapi/cli/php run-tests.php ext/mbstring/020.phpt
[Test results]
--------------
Test results are printed to standard output. If there is a failed test,
the "run-tests.php" script saves the result, the expected result and the
code executed to the test script directory. For example, if
ext/myext/tests/myext.phpt fails to pass, the following files are created:
ext/myext/tests/myext.php - actual test file executed
ext/myext/tests/myext.log - log of test execution (L)
ext/myext/tests/myext.exp - expected output (E)
ext/myext/tests/myext.out - output from test script (O)
ext/myext/tests/myext.diff - diff of .out and .exp (D)
Failed tests are always bugs. Either the test is bugged or not considering
factors applying to the tester's environment, or there is a bug in PHP.
If this is a known bug, we strive to provide bug numbers, in either the
test name or the file name. You can check the status of such a bug, by
going to: http://bugs.php.net/12345 where 12345 is the bug number.
For clarity and automated processing, bug numbers are prefixed by a hash
sign '#' in test names and/or test cases are named bug12345.phpt.
NOTE: The files generated by tests can be selected by setting the
environment variable TEST_PHP_LOG_FORMAT. For each file you want to be
generated use the character in brackets as shown above (default is LEOD).
The php file will be generated always.
NOTE: You can set environment variable TEST_PHP_DETAILED to enable
detailed test information.
[Automated testing]
If you like to keep up to speed, with latest developments and quality
assurance, setting the environment variable NO_INTERACTION to 1, will not
prompt the tester for any user input.
Normally, the exit status of "make test" is zero, regardless of the results
of independent tests. Set the environment variable REPORT_EXIT_STATUS to 1,
and "make test" will set the exit status ("$?") to non-zero, when an
individual test has failed.
Example script to be run by cron(1):
========== qa-test.sh =============
#!/bin/sh
CO_DIR=$HOME/cvs/php4
MYMAIL=qa-test@domain.com
TMPDIR=/var/tmp
TODAY=`date +"%Y%m%d"`
# Make sure compilation enviroment is correct
CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
export MAKE=gmake
export CC=gcc
# Set test environment
export NO_INTERACTIVITY=1
export REPORT_EXIT_STATUS=1
cd $CO_DIR
cvs update . >>$TMPDIR/phpqatest.$TODAY
./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
$MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
if test $? -gt 0
then
cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
fi
========== end of qa-test.sh =============
NOTE: the exit status of run-tests.php will be 1 when
REPORT_EXIT_STATUS is set. The result of "make test" may be higher
than that. At present, gmake 3.79.1 returns 2, so it is
advised to test for non-zero, rather then a specific value.
[Creating new test files]
-------------------------
Writing test file is very easy if you are used to PHP.
Here is an actual test file from standard module.
===== ext/standard/tests/strings/strtr.phpt =======
--TEST--
strtr() function
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$trans = array("hello"=>"hi", "hi"=>"hello", "a"=>"A", "world"=>"planet");
var_dump(strtr("# hi all, I said hello world! #", $trans));
?>
--EXPECT--
string(32) "# hello All, I sAid hi planet! #"
===== ext/standard/tests/strings/strtr.phpt =======
As you can see the file is devided into several sections. Below is a
list of all possible sections:
"--TEST--" is title of the test (required).
"--SKIPIF--" is condition when to skip this test (optional).
"--POST--" is POST variable passed to test script (optional).
"--GET--" is GET variable passed to test script (optional).
"--INI--" each line contains an ini setting e.g. foo=bar (optional).
"--FILE--" is the test script (required).
"--EXPECT--" is the expected output from the test script (required).
"--EXPECTF--" is an alternative of --EXPECT--. The difference is that
this form uses sscanf for output validation (alternative).
"--EXPECTREGEX--" is an alternative of --EXPECT--. This form allows the tester
to specify the result in a regular expression (alternative).
A test must at least contain the sections TEST, FILE and either EXPECT
or EXPECTF. When a test is called run-test.php takes the name from the
TEST section and writes the FILE section into a ".php" file with the
same name as the ".phpt" file. This ".php" file will then be executed
and its output compared to the contents of the EXPECT section. It is a
good idea to generate output with var_dump() calls.
/ext/standard/tests/strings/str_shuffle.phpt is a good example for using
EXPECTF instead of EXPECT. From time to time the algorithm used for shuffle
changed and sometimes the machine used to execute the code has influence
on the result of shuffle. But it always returns a three character string
detectable by %s. Other scan-able forms are %i for integers, %d for numbers
only, %f for floating point values, %c for single characters and %x for
hexadecimal values.
==== /ext/standard/tests/strings/str_shuffle.phpt ===
--TEST--
Testing str_shuffle.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = '123';
var_dump(str_shuffle($s));
var_dump($s);
?>
--EXPECTF--
string(3) %s
string(3) "123"
==== end of /ext/standard/tests/strings/str_shuffle.phpt ===
/ext/standard/tests/strings/strings001.phpt is a good example for using
EXPECTREGEX instead of EXPECT. This test also shows that in EXPECTREGEX
some characters need to be escaped since otherwise they would be
interpreted as a regular expression.
==== /ext/standard/tests/strings/strings001.phpt ===
--TEST--
Test whether strstr() and strrchr() are binary safe.
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example. */
$s = "alabala nica".chr(0)."turska panica";
var_dump(strstr($s, "nic"));
var_dump(strrchr($s," nic"));
?>
--EXPECTREGEX--
string\(18\) \"nica\x00turska panica\"
string\(19\) \" nica\x00turska panica\"
==== end of /ext/standard/tests/strings/strings001.phpt ===
Some tests depend on modules or functions available only in certain versions
or they even require minimum version of php or zend. These tests should be
skipped when the requirement cannot be fullfilled. To achieve this you can
use the SKIPIF section. To tell run-test.php that your test should be skipped
the SKIPIF section must print out the word "skip" followed by a reason why
the test should skip.
==== /ext/exif/tests/exif005.phpt ===
--TEST--
Check for exif_read_data, unusual IFD start
--SKIPIF--
<?php
if (!extension_loaded('exif')) print 'skip exif extension not available';
?>
--FILE--
<?php
/* Do not change this test it is a REATME.TESTING example.
* test5.jpg is a 1*1 image that contains an Exif section with ifd = 00000009h
*/
$image = exif_read_data('./ext/exif/tests/test5.jpg','',true,false);
var_dump($image['IFD0']);
?>
--EXPECT--
array(2) {
["ImageDescription"]=>
string(11) "Ifd00000009"
["DateTime"]=>
string(19) "2002:10:18 20:06:00"
}
==== end of /ext/exif/tests/exif005.phpt ===
Test script and SKIPIF code should be directly written into *.phpt. However,
it is recommended to use include files when more test scripts depend on the
same SKIPIF code or when certain test files need the same values for some
input. But no file used by any test should have one of the following
extensions: ".php", ".log", ".exp", ".out" or ".diff".
Tests should be named according to the following list:
Class: Name: Example:
Tests for bugs bug<bugid>.phpt bug17123.phpt
Tests for functions <functionname>.phpt dba_open.phpt
General tests for extensions <extname><no>.phpt dba3.phpt
When you use an include file for the SKIPIF section it should be named
"skipif.inc" and an include file used in the FILE section of many tests
should be named "test.inc".
NOTE: All tests should run correctly with error_reporting(E_ALL) and
display_errors=1. This is the default when called from run-test.php.
If you have a good reason for lowering the error reporting, use --INI--
section and comment this in your testcode.
NOTE: If your test intentionally generates a PHP warning message use
$php_errormsg variable, which you can then output. This will result
in a consistent error message output across all platforms and PHP
configurations, preventing your test from failing due inconsistencies
in the error message content.
[How to help us]
----------------
If you find bug in PHP, you can submit bug report AND test script
for us. You don't have to write complete script, just give us test
script with following format. Please test the script and make sure
you write the correct ACTUAL OUTPUT and EXPECTED OUTPUT before you
submit.
<?php
/*
Bug #12345
substr() bug. Do not return expected string.
ACTUAL OUTPUT
XYXA
EXPECTED OUTPUT
ABCD
*/
$str = "XYZABCD";
echo substr($str,3,7);
?>
-123
View File
@@ -1,123 +0,0 @@
PHP Build System V5 Overview
- supports Makefile.ins during transition phase
- not-really-portable Makefile includes have been eliminated
- supports separate build directories without VPATH by using
explicit rules only
- does not waste disk-space/CPU-time for building temporary libraries
=> especially noticeable on slower systems
- slow recursive make replaced with one global Makefile
- eases integration of proper dependencies
- adds PHP_DEFINE(what[, value]) which creates a single include-file
per what. This will allow more fine-grained dependencies.
- abandoning the "one library per directory" concept
- improved integration of the CLI
- several new targets
build-modules: builds and copies dynamic modules into modules/
install-cli: installs the CLI only, so that the install-sapi
target does only what its name says
- finally abandoned automake (still requires aclocal at this time)
- changed some configure-time constructs to run at buildconf-time
- upgraded shtool to 1.5.4
- removed $(moduledir) (use EXTENSION_DIR)
The Reason For a New System
It became more and more apparent that there is a severe need
for addressing the portability concerns and improving the chance
that your build is correct (how often have you been told to
"make clean"? When this is done, you won't need to anymore).
If You Build PHP on a Unix System
You, as a user of PHP, will notice no changes. Of course, the build
system will be faster, look better and work smarter.
If You Are Developing PHP
Extension developers:
Makefile.ins are abandoned. The files which are to be compiled
are specified in the config.m4 now using the following macro:
PHP_NEW_EXTENSION(foo, foo.c bar.c baz.cpp, $ext_shared)
E.g. this enables the extension foo which consists of three source-code
modules, two in C and one in C++. And, depending on the user's wishes,
the extension will even be built as a dynamic module.
The full syntax:
PHP_NEW_EXTENSION(extname, sources [, shared [,sapi_class[, extra-cflags]]])
Please have a look at acinclude.m4 for the gory details and meanings
of the other parameters.
And that's basically it for the extension side.
If you previously built sub-libraries for this module, add
the source-code files here as well. If you need to specify
separate include directories, do it this way:
PHP_NEW_EXTENSION(foo, foo.c mylib/bar.c mylib/gregor.c,,,-I@ext_srcdir@/lib)
E.g. this builds the three files which are located relative to the
extension source directory and compiles all three files with the
special include directive (@ext_srcdir@ is automatically replaced).
Now, you need to tell the build system that you want to build files
in a directory called $ext_builddir/lib:
PHP_ADD_BUILD_DIR($ext_builddir/lib)
Make sure to call this after PHP_NEW_EXTENSION, because $ext_builddir
is only set by the latter.
If you have a complex extension, you might to need add special
Make rules. You can do this by calling PHP_ADD_MAKEFILE_FRAGMENT
in your config.m4 after PHP_NEW_EXTENSION.
This will read a file in the source-dir of your extension called
Makefile.frag. In this file, $(builddir) and $(srcdir) will be
replaced by the values which are correct for your extension
and which are again determined by the PHP_NEW_EXTENSION macro.
Make sure to prefix *all* relative paths correctly with either
$(builddir) or $(srcdir). Because the build system does not
change the working directory anymore, we must use either
absolute paths or relative ones to the top build-directory.
Correct prefixing ensures that.
SAPI developers:
Instead of using PHP_SAPI=foo/PHP_BUILD_XYZ, you will need to type
PHP_SELECT_SAPI(name, type, sources.c)
I.e. specify the source-code files as above and also pass the
information regarding how PHP is supposed to be built (shared
module, program, etc).
For example for APXS:
PHP_SELECT_SAPI(apache, shared, sapi_apache.c mod_php4.c php_apache.c)
General info
The foundation for the new system is the flexible handling of
sources and their contexts. With the help of macros you
can define special flags for each source-file, where it is
located, in which target context it can work, etc.
Have a look at the well documented macros
PHP_ADD_SOURCES(_X) in acinclude.m4.
-126
View File
@@ -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'
-175
View File
@@ -1,175 +0,0 @@
Things to do or at least think about doing in the future. Name in
parenthesis means that person has taken on this project.
Zend
----
For PHP 4.3.0:
* Allow foreach ($array as $k => &$val) syntax. right now we cannot
traverse an array without copying each element.
* Allow foreach ($array as $k => list($a, $b)) syntax for multi
dimensional arrays.
* Look at replacing c-lib call tolower().
* Make hash API functions work with HASH_OF() to save time.
* Allow to set a default value for call-by-reference-parameters.
eg: function hello (&$pallo = NULL) {}
* Disallow function(method) redefinition in class.
* Add configure test to determine if dlsym() requires underscore and set
DLSYM_NEEDS_UNDERSCORE accordingly. Perl and zsh have it in configure,
for example. (DONE?)
For PHP 5.0.0:
* Native large number support (probably with GNU GMP)
* Const'ify APIs. Right now, many functions leave parameters untouched,
but don't declare those as const. This makes interaction with other
interfaces difficult which pass const parameters to us.
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?)
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.
Other
* use thread-safe resolver functions (either require BIND 8 or adns).
* implement javadoc based function docs template system.
* provide optional IPv6 support.
* find a better way to implement script timeouts. SIGVTALRM is used
by some POSIX threads implementations (i.e. OpenBSD) and is not
available in ZTS mode.
* Implement flush feature suitable for nested output buffers.
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
-------
* Add an ini directive to specify the size of decompression buffer.
The default 4k is too small for large files and also requires much time
for decompression. 40k is suitable for such files, however it may be too
much under certain environments. There should be appropriate default
settings for the various SAPI modules (e.g. apache and cli).
ext/curl
--------
* 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/odbc
--------
For PHP 4.3.0:
* update all php_error calls to php_error_docref where valid
* integrate EXPERIMENTAL ODBC update for use in PHP 5.0, use for
testing purposes only.
For PHP 5.0.0
* Activate EXPERIMENTAL ODBC codebase update
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()
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
-3
View File
@@ -1,3 +0,0 @@
- clean up .cvsignores
- purge Makefile.ins and replace PHP_EXTENSION in config.m4s
with appropiate calls to PHP_NEW_EXTENSION
-114
View File
@@ -1,114 +0,0 @@
This is an overview over existing segfaults in the current PHP source
tree.
Fixed:
mb_convert_encoding (Moriyoshi)
socket_iovec_alloc (Rasmus)
exif_imagetype,exif_thumbnail (Rasmus)
dbase_open (Rasmus)
array_pad (Rasmus)
setlocale (Rasmus)
unregister_tick_function (Rasmus)
bcsub (Rasmus)
str_repeat (Ilia)
imagecopyresized (Ilia)
mhash_keygen_s2k (Ilia)
bundled gd (Ilia)
mb_ereg, mb_ereg_match, mb_eregi, mb_split (Moriyoshi)
xml_parser_create (Moriyoshi)
ob_start (Sascha)
imagecreate/-truecolor (Sascha)
flock (Sascha)
register_shutdown_function (Sascha)
mb_strcut('', [number greater than the length of first arg]) (Moriyoshi)
ext/exif, ext/dba (Marcus)
php_base64_encode (Moriyoshi)
Open:
the dbase extension (1)
socket_select (2)
pack (3)
(1) heap corruption, mostly visible in malloc-related calls. Whether you see
this or not might depend on your libc/compiler. Hard to track down,
because the result of the corruption might be quite delayed.
Reproducable with glibc-2.3/gcc 3.2.2 by:
cat <<X | php do_crash
dbase_add_record
dbase_close
dbase_create
dbase_delete_record
dbase_get_record
dbase_get_record_with_names
dbase_numfields
dbase_numrecords
dbase_open
X
(2) heap corruption, dies in efree()/execute()
Methodology
1. Use a plain PHP_4_3 tree
2. Use the config.nice from ammendment 1.
3. Download the test script from:
<URL:http://schumann.cx/do_crash.txt>
4a. Use the scripts funcparse.awk/genfunclist.sh from phpdoc/scripts
for creating a plain text function list. Feed that list to
the script. Avoid calls like pcntl_fork. Manually remove functions
which take too long to finish/eat up all memory.
4b. For testing a single function, echo the name of the function to
the script like this:
echo dbase_open | php do_crash.txt
(3) multiple integer overflows, ex. pack("d4294967297", 2);
Amendment 1.
CFLAGS='-O0 -g' \
'../src/php4/configure' \
'--enable-pcntl' \
'--enable-shmop' \
'--enable-sysvsem' \
'--enable-sysvshm' \
'--enable-wddx' \
'--enable-yp' \
'--enable-filepro' \
'--enable-ftp' \
'--enable-dba' \
'--enable-dbase' \
'--enable-dio' \
'--enable-exif' \
'--enable-mbstring' \
'--enable-mbregex' \
'--enable-sockets' \
'--enable-bcmath' \
'--enable-calendar' \
'--enable-pcntl' \
'--enable-shmop' \
'--enable-sysvsem' \
'--enable-sysvshm' \
'--enable-wddx' \
'--enable-yp' \
'--enable-filepro' \
'--enable-ftp' \
'--enable-dba' \
'--enable-dbase' \
'--enable-dio' \
'--enable-exif' \
'--enable-mbstring' \
'--enable-mbregex' \
'--enable-sockets' \
'--enable-bcmath' \
'--enable-calendar' \
"$@"
-26
View File
@@ -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.
-6
View File
@@ -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:
-2
View File
@@ -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
-627
View File
@@ -1,627 +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>
#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(args)
#define TSRM_SAFE_RETURN_RSRC(array, offset, range) \
if (offset==0) { \
return &array; \
} else { \
return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \
}
#endif
#if defined(PTHREADS)
/* Thread local storage */
static pthread_key_t tls_key;
#elif defined(TSRM_ST)
static int tls_key;
#elif defined(TSRM_WIN32)
static DWORD tls_key;
#elif defined(BETHREADS)
static int32 tls_key;
#endif
/* Startup TSRM (call once for the entire process) */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename)
{
#if defined(GNUPTH)
pth_init();
#elif defined(PTHREADS)
pthread_key_create( &tls_key, 0 );
#elif defined(TSRM_ST)
st_init();
st_key_create(&tls_key, 0);
#elif defined(TSRM_WIN32)
tls_key = TlsAlloc();
#elif defined(BETHREADS)
tls_key = tls_allocate();
#endif
tsrm_error_file = stderr;
tsrm_error_set(debug_level, debug_filename);
tsrm_tls_table_size = expected_threads;
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
if (!tsrm_tls_table) {
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
return 0;
}
id_count=0;
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_setspecific(tls_key, 0);
pthread_key_delete(tls_key);
#elif defined(TSRM_WIN32)
TlsFree(tls_key);
#endif
}
/* allocates a new thread-safe-resource id */
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor)
{
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);
#elif defined(BETHREADS)
tls_set(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);
#elif defined(BETHREADS)
thread_resources = (tsrm_tls_entry*)tls_get(tls_key);
#else
thread_resources = NULL;
#endif
if (thread_resources) {
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
/* Read a specific resource from the thread's resources.
* This is called outside of a mutex, so have to be aware about external
* changes to the structure as we read it.
*/
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
}
thread_id = tsrm_thread_id();
} else {
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();
#elif defined(BETHREADS)
return find_thread(NULL);
#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();
#elif defined(BETHREADS)
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
mutexp->ben = 0;
mutexp->sem = create_sem(1, "PHP sempahore");
#endif
#ifdef THR_DEBUG
printf("Mutex created thread: %d\n",mythreadid());
#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);
#elif defined(BETHREADS)
delete_sem(mutexp->sem);
free(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);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, 1) != 0)
return acquire_sem(mutexp->sem);
return 0;
#endif
}
/* Unlock a mutex */
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
{
TSRM_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);
#elif defined(BETHREADS)
if (atomic_add(&mutexp->ben, -1) != 1)
return release_sem(mutexp->sem);
return 0;
#endif
}
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
{
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
View File
@@ -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
-161
View File
@@ -1,161 +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
# include "tsrm_config.w32.h"
#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>
#elif defined(BETHREADS)
#include <kernel/OS.h>
#include <TLS.h>
#endif
typedef int ts_rsrc_id;
/* Define THREAD_T and MUTEX_T */
#ifdef TSRM_WIN32
# define THREAD_T DWORD
# define MUTEX_T CRITICAL_SECTION *
#elif defined(NETWARE)
# define THREAD_T NXThreadId_t
# define MUTEX_T NXMutex_t *
#elif defined(GNUPTH)
# define THREAD_T pth_t
# define MUTEX_T pth_mutex_t *
#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
#elif defined(BETHREADS)
# define THREAD_T thread_id
typedef struct {
sem_id sem;
int32 ben;
} beos_ben;
# define MUTEX_T beos_ben *
#endif
typedef void (*ts_allocate_ctor)(void *, void ***);
typedef void (*ts_allocate_dtor)(void *, void ***);
#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
View File
@@ -1 +0,0 @@
#undef PTHREADS
-5
View File
@@ -1,5 +0,0 @@
AC_DEFUN(AM_SET_LIBTOOL_VARIABLE,[
LIBTOOL='$(SHELL) $(top_builddir)/libtool $1'
])
-43
View File
@@ -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
-33
View File
@@ -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
-31
View File
@@ -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)
-44
View File
@@ -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 */
-165
View File
@@ -1,165 +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,[
if test "$beos_threads" = "1"; then
pthreads_working="yes"
ac_cv_pthreads_cflags=""
else
save_CFLAGS=$CFLAGS
save_LIBS=$LIBS
PTHREADS_ASSIGN_VARS
PTHREADS_CHECK_COMPILE
LIBS=$save_LIBS
CFLAGS=$save_CFLAGS
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
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
-128
View File
@@ -1,128 +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 "$beos_threads" = "1"; then
AC_DEFINE(BETHREADS, 1, Whether to use native BeOS threads)
else
if test "$pthreads_working" != "yes"; then
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
fi
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
AC_MSG_CHECKING(for POSIX threads)
AC_MSG_RESULT(yes)
fi
])
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
])
-9
View File
@@ -1,9 +0,0 @@
#ifndef TSRM_CONFIG_NW_H
#define TSRM_CONFIG_NW_H
#define HAVE_UTIME 1
/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
/* #define HAVE_ALLOCA 1 */
#endif
-19
View File
@@ -1,19 +0,0 @@
#ifndef TSRM_CONFIG_W32_H
#define TSRM_CONFIG_W32_H
#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
#include <malloc.h>
#include <stdlib.h>
#include <crtdbg.h>
#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
# define inline __forceinline
#else
# define inline
#endif
#endif
-58
View File
@@ -1,58 +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
#if HAVE_ALLOCA_H && !defined(_ALLOCA_H)
# include <alloca.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# ifndef HAVE_ALLOCA_H
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#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
View File
@@ -1,260 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "TSRM.h"
#ifdef NETWARE
#ifdef USE_MKFIFO
#include <sys/stat.h>
#elif !defined(USE_PIPE_OPEN) /* NXFifoOpen */
#include <nks/fsio.h>
#endif
#include <nks/vm.h>
#include <nks/memory.h>
#include <string.h>
#include "mktemp.h"
/* strtok() call in LibC is abending when used in a different address space -- hence using
PHP's version itself for now : Venkat (30/4/02) */
#include "tsrm_strtok_r.h"
#define tsrm_strtok_r(a,b,c) strtok((a),(b))
#define WHITESPACE " \t"
#define MAX_ARGS 10
TSRM_API FILE* popen(const char *commandline, const char *type)
{
char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
char *filePath = NULL;
char *ptr = NULL;
int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
FILE *stream = NULL;
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
int pipe_handle;
int mode = O_RDONLY;
#else
NXHandle_t pipe_handle;
NXMode_t mode = NX_O_RDONLY;
#endif
NXExecEnvSpec_t envSpec;
NXNameSpec_t nameSpec;
NXVmId_t newVM = 0;
/* Check for validity of input parameters */
if (!commandline || !type)
return NULL;
/* Get temporary file name */
filePath = mktemp(tempName);
/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/
if (!filePath)
return NULL;
/* Set pipe mode according to type -- for now allow only "r" or "w" */
if (strcmp(type, "r") == 0)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
mode = O_RDONLY;
#else
mode = NX_O_RDONLY;
#endif
else if (strcmp(type, "w") == 0)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
mode = O_WRONLY;
#else
mode = NX_O_WRONLY;
#endif
else
return NULL;
#ifdef USE_PIPE_OPEN
pipe_handle = pipe_open(filePath, mode);
/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/
if (pipe_handle == -1)
return NULL;
#elif defined(USE_MKFIFO)
pipe_handle = mkfifo(filePath, mode);
consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
if (pipe_handle == -1)
return NULL;
#else
/*
- NetWare doesn't require first parameter
- Allowing LibC to choose the buffer size for now
*/
err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/
if (err)
return NULL;
#endif
/* Copy the environment variables in preparation for the spawn call */
envCount = NXGetEnvCount() + 1; /* add one for NULL */
env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0);
if (!env)
return NULL;
err = NXCopyEnv(env, envCount);
consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err);
if (err)
{
NXMemFree (env);
return NULL;
}
/* Separate commandline string into words */
consoleprintf ("PHP | popen: commandline = %s\n", commandline);
ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
ptrLen = strlen(ptr);
command = (char*)malloc(ptrLen + 1);
if (!command)
{
NXMemFree (env);
return NULL;
}
strcpy (command, ptr);
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
while (ptr && (argc < MAX_ARGS))
{
ptrLen = strlen(ptr);
argv[argc] = (char*)malloc(ptrLen + 1);
if (!argv[argc])
{
NXMemFree (env);
if (command)
free (command);
for (i = 0; i < argc; i++)
{
if (argv[i])
free (argv[i]);
}
return NULL;
}
strcpy (argv[argc], ptr);
argc++;
ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
}
consoleprintf ("PHP | popen: commandline string parsed into tokens\n");
/* Setup the execution environment and spawn new process */
envSpec.esFlags = 0; /* Not used */
envSpec.esArgc = argc;
envSpec.esArgv = (void**)argv;
envSpec.esEnv = (void**)env;
envSpec.esStdin.ssType =
envSpec.esStdout.ssType = NX_OBJ_FIFO;
envSpec.esStderr.ssType = NX_OBJ_FILE;
/*
envSpec.esStdin.ssHandle =
envSpec.esStdout.ssHandle =
envSpec.esStderr.ssHandle = -1;
*/
envSpec.esStdin.ssPathCtx =
envSpec.esStdout.ssPathCtx =
envSpec.esStderr.ssPathCtx = NULL;
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
if (mode == O_RDONLY)
#else
if (mode == NX_O_RDONLY)
#endif
{
envSpec.esStdin.ssPath = filePath;
envSpec.esStdout.ssPath = stdout;
}
else /* Write Only */
{
envSpec.esStdin.ssPath = stdin;
envSpec.esStdout.ssPath = filePath;
}
envSpec.esStderr.ssPath = stdout;
nameSpec.ssType = NX_OBJ_FIFO;
/* nameSpec.ssHandle = 0; */ /* Not used */
nameSpec.ssPathCtx = NULL; /* Not used */
nameSpec.ssPath = argv[0];
consoleprintf ("PHP | popen: environment setup\n");
err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err);
if (!err)
/* Get file pointer corresponding to the pipe (file) opened */
stream = fdopen(pipe_handle, type);
/* Clean-up */
if (env)
NXMemFree (env);
if (pipe_handle)
#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
close(pipe_handle);
#else
NXClose(pipe_handle);
#endif
if (command)
free (command);
for (i = 0; i < argc; i++)
{
if (argv[i])
free (argv[i]);
}
consoleprintf ("PHP | popen: all clean-up done, returning...\n");
return stream;
}
TSRM_API int pclose(FILE* stream)
{
int err = 0;
NXHandle_t fd = 0;
/* Get the process associated with this pipe (file) handle and terminate it */
fd = fileno(stream);
NXClose (fd);
err = fclose(stream);
return err;
}
#endif
-28
View File
@@ -1,28 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Venkat Raghavan S <rvenkat@novell.com> |
+----------------------------------------------------------------------+
*/
#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
-63
View File
@@ -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
-6
View File
@@ -1,6 +0,0 @@
#ifndef TSRM_STRTOK_R
#define TSRM_STRTOK_R
char *tsrm_strtok_r(char *s, const char *delim, char **last);
#endif
-860
View File
@@ -1,860 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: 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
#ifndef HAVE_REALPATH
#define realpath(x,y) strcpy(y,x)
#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 && element[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 && element[0] == '.' && element[1] == '.')
#endif
#ifndef IS_DIRECTORY_CURRENT
#define IS_DIRECTORY_CURRENT(element, len) \
(len == 1 && element[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 use_realpath)
{
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(NETWARE)
/* cwd_length can be 0 when getcwd() fails.
* This can happen under solaris when a dir does not have read permissions
* but *does* have execute permissions */
if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
if (use_realpath && realpath(path, resolved_path)) {
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 (use_realpath && 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_amount = COPY_WHEN_ABSOLUTE(path_copy);
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;
}
if (state->cwd_length > 0 || IS_ABSOLUTE_PATH(path, path_length)) {
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);
while (ptr) {
ptr_length = strlen(ptr);
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);
}
if (state->cwd_length == COPY_WHEN_ABSOLUTE(state->cwd)) {
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++;
}
} else {
state->cwd = (char *) realloc(state->cwd, path_length+1);
memcpy(state->cwd, path, path_length+1);
state->cwd_length = path_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)?-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;
}
if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */
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;
char *retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
if (virtual_file_ex(&new_state, path, NULL, 1)==0) {
int len = new_state.cwd_length>MAXPATHLEN-1?MAXPATHLEN-1:new_state.cwd_length;
memcpy(real_path, new_state.cwd, len);
real_path[len] = '\0';
retval = real_path;
} else {
retval = NULL;
}
CWD_STATE_FREE(&new_state);
return retval;
}
CWD_API int virtual_filepath_ex(const char *path, char **filepath, verify_path_func verify_path TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
retval = virtual_file_ex(&new_state, path, verify_path, 1);
*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, 1);
f = fopen(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return f;
}
#if !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, pathname, NULL, 1);
ret = access(new_state.cwd, mode);
CWD_STATE_FREE(&new_state);
return ret;
}
#endif
#if HAVE_UTIME
CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC)
{
cwd_state new_state;
int ret;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, filename, NULL, 0);
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, 1);
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, 0);
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, 1);
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, 1);
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, 0);
oldname = old_state.cwd;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, newname, NULL, 0);
newname = new_state.cwd;
retval = rename(oldname, newname);
CWD_STATE_FREE(&old_state);
CWD_STATE_FREE(&new_state);
return retval;
}
#if !(defined(NETWARE) && defined(CLIB_STAT_PATCH))
CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 1);
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, 1);
retval = stat(new_state.cwd, (struct stat*)buf);
CWD_STATE_FREE(&new_state);
return retval;
}
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC)
{
cwd_state new_state;
int retval;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
virtual_file_ex(&new_state, path, NULL, 0);
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, 0);
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, 1);
#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, 0);
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, 1);
retval = opendir(new_state.cwd);
CWD_STATE_FREE(&new_state);
return retval;
}
#ifdef TSRM_WIN32
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
return popen_ex(command, type, CWDG(cwd).cwd, NULL);
}
#elif defined(NETWARE)
/* On NetWare, the trick of prepending "cd cwd; " doesn't work so we need to perform
a VCWD_CHDIR() and mutex it
*/
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
char prev_cwd[MAXPATHLEN];
char *getcwd_result;
FILE *retval;
getcwd_result = VCWD_GETCWD(prev_cwd, MAXPATHLEN);
if (!getcwd_result) {
return NULL;
}
#ifdef ZTS
tsrm_mutex_lock(cwd_mutex);
#endif
VCWD_CHDIR(CWDG(cwd).cwd);
retval = popen(command, type);
VCWD_CHDIR(prev_cwd);
#ifdef ZTS
tsrm_mutex_unlock(cwd_mutex);
#endif
return retval;
}
#else /* Unix */
CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC)
{
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:
*/
-277
View File
@@ -1,277 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: 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
#if defined(__osf__) || defined(_AIX)
#include <errno.h>
#endif
#ifdef TSRM_WIN32
#include "readdir.h"
#include <sys/utime.h>
/* mode_t isn't defined on Windows */
typedef unsigned short mode_t;
#define DEFAULT_SLASH '\\'
#define DEFAULT_DIR_SEPARATOR ';'
#define IS_SLASH(c) ((c) == '/' || (c) == '\\')
#define IS_SLASH_P(c) (*(c) == '/' || \
(*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))
/* COPY_WHEN_ABSOLUTE also takes path as argument because netware needs it
* to account for volume name that is unique to NetWare absolute paths
*/
#define COPY_WHEN_ABSOLUTE(path) 2
#define IS_ABSOLUTE_PATH(path, len) \
(len >= 2 && ((isalpha(path[0]) && path[1] == ':') || (IS_SLASH(path[0]) && IS_SLASH(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(path) 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 !defined(TSRM_WIN32)
CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC);
#endif
/* On AIX & Tru64 when a file does not exist realpath() returns
* NULL, and sets errno to ENOENT. Unlike in other libc implementations
* the destination is not filled and remains undefined. Therefor, we
* must populate it manually using strcpy as done on systems with no
* realpath() function.
*/
#if defined(__osf__) || defined(_AIX)
static char *php_realpath_hack(char *src, char *dest)
{
char *ret;
if ((ret = realpath(src, dest)) == NULL && errno == ENOENT) {
return strcpy(dest, src);
} else {
return ret;
}
}
#endif
#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, int use_realpath);
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_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)
#define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode 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)
#define VCWD_ACCESS(pathname, mode) access(pathname, mode)
#ifdef HAVE_REALPATH
#if defined(__osf__) || defined(_AIX)
#define VCWD_REALPATH(path, real_path) php_realpath_hack(path, real_path)
#else
#define VCWD_REALPATH(path, real_path) realpath(path, real_path)
#endif
#else
#define VCWD_REALPATH(path, real_path) strcpy(real_path, path)
#endif
#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 */
-362
View File
@@ -1,362 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <process.h>
#include <time.h>
#include "TSRM.h"
#ifdef TSRM_WIN32
#include "tsrm_win32.h"
#ifdef ZTS
static ts_rsrc_id win32_globals_id;
#else
static tsrm_win32_globals win32_globals;
#endif
static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC)
{
globals->process = NULL;
globals->shm = NULL;
globals->process_size = 0;
globals->shm_size = 0;
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
}
static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC)
{
shm_pair *ptr;
if (globals->process) {
free(globals->process);
}
if (globals->shm) {
for (ptr = globals->shm; ptr < (globals->shm + globals->shm_size); ptr++) {
UnmapViewOfFile(ptr->addr);
CloseHandle(ptr->segment);
UnmapViewOfFile(ptr->descriptor);
CloseHandle(ptr->info);
}
free(globals->shm);
}
free(globals->comspec);
}
TSRM_API void tsrm_win32_startup(void)
{
#ifdef ZTS
ts_allocate_id(&win32_globals_id, sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
#else
tsrm_win32_ctor(&win32_globals TSRMLS_CC);
#endif
}
TSRM_API void tsrm_win32_shutdown(void)
{
#ifndef ZTS
tsrm_win32_dtor(&win32_globals TSRMLS_CC);
#endif
}
static process_pair *process_get(FILE *stream TSRMLS_DC)
{
process_pair *ptr;
process_pair *newptr;
for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
if (ptr->stream == stream) {
break;
}
}
if (ptr < (TWG(process) + TWG(process_size))) {
return ptr;
}
newptr = (process_pair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(process_pair));
if (newptr == NULL) {
return NULL;
}
TWG(process) = newptr;
ptr = newptr + TWG(process_size);
TWG(process_size)++;
return ptr;
}
static shm_pair *shm_get(int key, void *addr)
{
shm_pair *ptr;
shm_pair *newptr;
TSRMLS_FETCH();
for (ptr = TWG(shm); ptr < (TWG(shm) + TWG(shm_size)); ptr++) {
if (!ptr->descriptor) {
continue;
}
if (!addr && ptr->descriptor->shm_perm.key == key) {
break;
} else if (ptr->addr == addr) {
break;
}
}
if (ptr < (TWG(shm) + TWG(shm_size))) {
return ptr;
}
newptr = (shm_pair*)realloc((void*)TWG(shm), (TWG(shm_size)+1)*sizeof(shm_pair));
if (newptr == NULL) {
return NULL;
}
TWG(shm) = newptr;
ptr = newptr + TWG(shm_size);
TWG(shm_size)++;
return ptr;
}
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
HANDLE copy, self = GetCurrentProcess();
if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
return NULL;
}
return copy;
}
TSRM_API FILE *popen(const char *command, const char *type)
{
return popen_ex(command, type, NULL, NULL);
}
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
{
FILE *stream = NULL;
int fno, str_len = strlen(type), read, mode;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
HANDLE in, out;
char *cmd;
process_pair *proc;
TSRMLS_FETCH();
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = TRUE;
security.lpSecurityDescriptor = NULL;
if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) {
return NULL;
}
memset(&startup, 0, sizeof(STARTUPINFO));
memset(&process, 0, sizeof(PROCESS_INFORMATION));
startup.cb = sizeof(STARTUPINFO);
startup.dwFlags = STARTF_USESTDHANDLES;
startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
read = (type[0] == 'r') ? TRUE : FALSE;
mode = ((str_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
if (read) {
in = dupHandle(in, FALSE);
startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startup.hStdOutput = out;
} else {
out = dupHandle(out, FALSE);
startup.hStdInput = in;
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c "));
sprintf(cmd, "%s /c %s", TWG(comspec), command);
if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, env, cwd, &startup, &process)) {
return NULL;
}
free(cmd);
CloseHandle(process.hThread);
proc = process_get(NULL TSRMLS_CC);
if (read) {
fno = _open_osfhandle((long)in, _O_RDONLY | mode);
CloseHandle(out);
} else {
fno = _open_osfhandle((long)out, _O_WRONLY | mode);
CloseHandle(in);
}
stream = _fdopen(fno, type);
proc->prochnd = process.hProcess;
proc->stream = stream;
return stream;
}
TSRM_API int pclose(FILE *stream)
{
DWORD termstat = 0;
process_pair *process;
TSRMLS_FETCH();
if ((process = process_get(stream TSRMLS_CC)) == NULL) {
return 0;
}
fflush(process->stream);
fclose(process->stream);
WaitForSingleObject(process->prochnd, INFINITE);
GetExitCodeProcess(process->prochnd, &termstat);
process->stream = NULL;
CloseHandle(process->prochnd);
return termstat;
}
TSRM_API int shmget(int key, int size, int flags)
{
shm_pair *shm;
char shm_segment[26], shm_info[29];
HANDLE shm_handle, info_handle;
BOOL created = FALSE;
if (size < 0) {
return -1;
}
sprintf(shm_segment, "TSRM_SHM_SEGMENT:%d", key);
sprintf(shm_info, "TSRM_SHM_DESCRIPTOR:%d", key);
shm_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_segment);
info_handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, shm_info);
if ((!shm_handle && !info_handle)) {
if (flags & IPC_EXCL) {
return -1;
}
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, shm_segment);
info_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(shm->descriptor), shm_info);
created = TRUE;
}
if ((!shm_handle || !info_handle)) {
return -1;
}
}
shm = shm_get(key, NULL);
shm->segment = shm_handle;
shm->info = info_handle;
shm->descriptor = MapViewOfFileEx(shm->info, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
if (created) {
shm->descriptor->shm_perm.key = key;
shm->descriptor->shm_segsz = size;
shm->descriptor->shm_ctime = time(NULL);
shm->descriptor->shm_cpid = getpid();
shm->descriptor->shm_perm.mode = flags;
shm->descriptor->shm_perm.cuid = shm->descriptor->shm_perm.cgid= 0;
shm->descriptor->shm_perm.gid = shm->descriptor->shm_perm.uid = 0;
shm->descriptor->shm_atime = shm->descriptor->shm_dtime = 0;
shm->descriptor->shm_lpid = shm->descriptor->shm_nattch = 0;
shm->descriptor->shm_perm.mode = shm->descriptor->shm_perm.seq = 0;
}
if (shm->descriptor->shm_perm.key != key || size > shm->descriptor->shm_segsz ) {
CloseHandle(shm->segment);
UnmapViewOfFile(shm->descriptor);
CloseHandle(shm->info);
return -1;
}
return key;
}
TSRM_API void *shmat(int key, const void *shmaddr, int flags)
{
shm_pair *shm = shm_get(key, NULL);
if (!shm->segment) {
return (void*)-1;
}
shm->descriptor->shm_atime = time(NULL);
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch++;
shm->addr = MapViewOfFileEx(shm->segment, FILE_MAP_ALL_ACCESS, 0, 0, 0, NULL);
return shm->addr;
}
TSRM_API int shmdt(const void *shmaddr)
{
shm_pair *shm = shm_get(0, (void*)shmaddr);
if (!shm->segment) {
return -1;
}
shm->descriptor->shm_dtime = time(NULL);
shm->descriptor->shm_lpid = getpid();
shm->descriptor->shm_nattch--;
return UnmapViewOfFile(shm->addr) ? 0 : -1;
}
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf) {
shm_pair *shm = shm_get(key, NULL);
if (!shm->segment) {
return -1;
}
switch (cmd) {
case IPC_STAT:
memcpy(buf, shm->descriptor, sizeof(struct shmid_ds));
return 0;
case IPC_SET:
shm->descriptor->shm_ctime = time(NULL);
shm->descriptor->shm_perm.uid = buf->shm_perm.uid;
shm->descriptor->shm_perm.gid = buf->shm_perm.gid;
shm->descriptor->shm_perm.mode = buf->shm_perm.mode;
return 0;
case IPC_RMID:
if (shm->descriptor->shm_nattch < 1) {
shm->descriptor->shm_perm.key = -1;
}
return 0;
default:
return -1;
}
}
#endif
-104
View File
@@ -1,104 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Daniel Beulshausen <daniel@php4win.de> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef TSRM_WIN32_H
#define TSRM_WIN32_H
#include "TSRM.h"
#include <windows.h>
struct ipc_perm {
int key;
unsigned short uid;
unsigned short gid;
unsigned short cuid;
unsigned short cgid;
unsigned short mode;
unsigned short seq;
};
struct shmid_ds {
struct ipc_perm shm_perm;
int shm_segsz;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
unsigned short shm_cpid;
unsigned short shm_lpid;
short shm_nattch;
};
typedef struct {
FILE *stream;
HANDLE prochnd;
} process_pair;
typedef struct {
void *addr;
HANDLE info;
HANDLE segment;
struct shmid_ds *descriptor;
} shm_pair;
typedef struct {
process_pair *process;
shm_pair *shm;
int process_size;
int shm_size;
char *comspec;
} tsrm_win32_globals;
#ifdef ZTS
# define TWG(v) TSRMG(win32_globals_id, tsrm_win32_globals *, v)
#else
# define TWG(v) (win32_globals.v)
#endif
#define IPC_PRIVATE 0
#define IPC_CREAT 00001000
#define IPC_EXCL 00002000
#define IPC_NOWAIT 00004000
#define IPC_RMID 0
#define IPC_SET 1
#define IPC_STAT 2
#define IPC_INFO 3
#define SHM_R PAGE_READONLY
#define SHM_W PAGE_READWRITE
#define SHM_RDONLY FILE_MAP_READ
#define SHM_RND FILE_MAP_WRITE
#define SHM_REMAP FILE_MAP_COPY
TSRM_API void tsrm_win32_startup(void);
TSRM_API void tsrm_win32_shutdown(void);
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env);
TSRM_API FILE *popen(const char *command, const char *type);
TSRM_API int pclose(FILE *stream);
TSRM_API int shmget(int key, int size, int flags);
TSRM_API void *shmat(int key, const void *shmaddr, int flags);
TSRM_API int shmdt(const void *shmaddr);
TSRM_API int shmctl(int key, int cmd, struct shmid_ds *buf);
#endif
-1
View File
@@ -1 +0,0 @@
/* Leave this file alone */
-1801
View File
File diff suppressed because it is too large. Load diff
-73
View File
@@ -1,73 +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. |
# +----------------------------------------------------------------------+
# | Author: Sascha Schumann <sascha@schumann.cx> |
# +----------------------------------------------------------------------+
#
# $Id$
#
#
# Makefile to generate build tools
#
ZENDDIR = Zend
SUBDIRS = $(ZENDDIR) TSRM
STAMP = buildmk.stamp
ALWAYS = generated_lists
all: $(STAMP) $(ALWAYS)
@$(MAKE) AMFLAGS=$(AMFLAGS) -s -f build/build2.mk
generated_lists:
@echo makefile_am_files = $(ZENDDIR)/Makefile.am \
TSRM/Makefile.am > $@
@echo config_h_files = $(ZENDDIR)/acconfig.h TSRM/acconfig.h >> $@
@echo config_m4_files = $(ZENDDIR)/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \
$(ZENDDIR)/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@
$(STAMP): build/buildcheck.sh
@build/buildcheck.sh $(STAMP)
snapshot:
distname='$(DISTNAME)'; \
if test -z "$$distname"; then \
distname='php4-snapshot'; \
fi; \
myname=`basename \`pwd\`` ; \
cd .. && cp -rp $$myname $$distname; \
cd $$distname; \
rm -f $(SUBDIRS) 2>/dev/null || true; \
for i in $(SUBDIRS); do \
test -d $$i || (test -d ../$$i && cp -rp ../$$i $$i); \
done; \
find . -type l -exec rm {} \; ; \
$(MAKE) AMFLAGS=--copy -f build/build.mk; \
cd ..; \
tar cf $$distname.tar $$distname; \
rm -rf $$distname $$distname.tar.*; \
bzip2 -9 $$distname.tar; \
md5sum $$distname.tar.bz2; \
sync; sleep 2; \
md5sum $$distname.tar.bz2; \
bzip2 -t $$distname.tar.bz2
cvsclean:
@for i in `find . -name .cvsignore`; do \
(cd `dirname $$i` 2>/dev/null && rm -rf `cat .cvsignore | grep -v config.nice` *.o *.a .libs || true); \
done
.PHONY: $(ALWAYS) snapshot cvsclean
-64
View File
@@ -1,64 +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. |
# +----------------------------------------------------------------------+
# | Author: Sascha Schumann <sascha@schumann.cx> |
# +----------------------------------------------------------------------+
#
# $Id$
#
include generated_lists
TOUCH_FILES = mkinstalldirs install-sh missing
LT_TARGETS = ltmain.sh config.guess config.sub
makefile_in_files = $(makefile_am_files:.am=.in)
makefile_files = $(makefile_am_files:e.am=e)
config_h_in = main/php_config.h.in
acconfig_h_SOURCES = acconfig.h.in $(config_h_files)
targets = $(TOUCH_FILES) configure $(config_h_in)
all: $(targets)
acconfig.h: $(acconfig_h_SOURCES)
@echo rebuilding $@
cat $(acconfig_h_SOURCES) > $@
SUPPRESS_WARNINGS = (egrep -v '(AC_TRY_RUN called without default to allow cross compiling|AC_PROG_CXXCPP was called before AC_PROG_CXX|defined in acinclude.m4 but never used|AC_PROG_LEX invoked multiple times)'||true)
$(config_h_in): configure acconfig.h
# explicitly remove target since autoheader does not seem to work
# correctly otherwise (timestamps are not updated)
@echo rebuilding $@
@rm -f $@
@autoheader 2>&1 | $(SUPPRESS_WARNINGS)
$(TOUCH_FILES):
touch $(TOUCH_FILES)
aclocal.m4: configure.in acinclude.m4
@echo rebuilding $@
@libtoolize=`./build/shtool path glibtoolize libtoolize`; \
$$libtoolize --copy --automake; \
ltpath=`dirname $$libtoolize`; \
ltfile=`cd $$ltpath/../share/aclocal; pwd`/libtool.m4; \
cat acinclude.m4 $$ltfile > $@
configure: aclocal.m4 configure.in $(config_m4_files)
@echo rebuilding $@
@autoconf 2>&1 | $(SUPPRESS_WARNINGS)
-93
View File
@@ -1,93 +0,0 @@
#! /bin/sh
# +----------------------------------------------------------------------+
# | 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: Stig Bakken <ssb@php.net> |
# | Sascha Schumann <sascha@schumann.cx> |
# +----------------------------------------------------------------------+
#
# $Id: buildcheck.sh,v 1.21.2.5 2003-07-01 04:25:32 sas Exp $
#
echo "buildconf: checking installation..."
stamp=$1
# autoconf 2.13 or newer
ac_version=`autoconf --version 2>/dev/null|head -1|sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
if test -z "$ac_version"; then
echo "buildconf: autoconf not found."
echo " You need autoconf version 2.13 or newer installed"
echo " to build PHP from CVS."
exit 1
fi
IFS=.; set $ac_version; IFS=' '
if test "$1" = "2" -a "$2" -lt "13" || test "$1" -lt "2"; then
echo "buildconf: autoconf version $ac_version found."
echo " You need autoconf version 2.13 or newer installed"
echo " to build PHP from CVS."
exit 1
else
echo "buildconf: autoconf version $ac_version (ok)"
fi
if test "$1" = "2" && test "$2" -ge "50"; then
echo "buildconf: Your version of autoconf likely contains buggy cache code."
echo " Running cvsclean for you."
echo " To avoid this, install autoconf-2.13 and automake-1.5."
./cvsclean
stamp=
fi
# libtoolize 1.4.3 or newer
# Prefer glibtoolize over libtoolize for Mac OS X compatibility
libtoolize=`./build/shtool path glibtoolize libtoolize 2> /dev/null`
lt_pversion=`$libtoolize --version 2>/dev/null|head -1|sed -e 's/^[^0-9]*//'`
if test "$lt_pversion" = ""; then
echo "buildconf: libtool not found."
echo " You need libtool version 1.4.3 or newer installed"
echo " to build PHP from CVS."
exit 1
fi
IFS=.; set $lt_pversion; IFS=' '
if test "$3" = ""; then
third=0
else
third=$3
fi
if test "$1" -gt "1" || test "$2" -ge "5" || (test "$2" -ge "4" && test "$third" -ge "3")
then
echo "buildconf: libtool version $lt_pversion (ok)"
else
echo "buildconf: libtool version $lt_pversion found."
echo " You need libtool version 1.4.3 or newer installed"
echo " to build PHP from CVS."
exit 1
fi
ltpath=`echo $libtoolize | sed -e 's#/[^/]*/[^/]*$##'`
ltfile="$ltpath/share/aclocal/libtool.m4"
if test -r "$ltfile"; then
:
else
echo "buildconf: $ltfile does not exist."
echo " Please reinstall libtool."
exit 1
fi
test -n "$stamp" && touch $stamp
exit 0
-8
View File
@@ -1,8 +0,0 @@
#!/bin/sh
#
# $Id$
dir=$1; shift
for stubfile in $dir/*/config0.m4 $dir/*/config.m4 $dir/*/config9.m4; do
echo "sinclude($stubfile)"
done
-41
View File
@@ -1,41 +0,0 @@
#! /bin/sh
# $Id: genif.sh,v 1.3 2002-03-22 10:22:41 sas Exp $
# replacement for genif.pl
infile=$1
shift
srcdir=$1
shift
extra_module_ptrs=$1
shift
awk=$1
shift
if test -z "$infile" || test -z "$srcdir"; then
echo "please supply infile and srcdir"
exit 1
fi
module_ptrs=$extra_module_ptrs
header_list=
olddir=`pwd`
cd $srcdir
for ext in ${1+"$@"} ; do
module_ptrs=" phpext_${ext}_ptr,@NEWLINE@$module_ptrs"
header_list="$header_list ext/$ext/*.h"
done
includes=`$awk -f ./build/print_include.awk $header_list`
cd $olddir
cat $infile | \
sed \
-e "s'@EXT_INCLUDE_CODE@'$includes'" \
-e "s'@EXT_MODULE_PTRS@'$module_ptrs'" \
-e 's/@NEWLINE@/\
/g'
-75
View File
@@ -1,75 +0,0 @@
# +----------------------------------------------------------------------+
# | PHP Version 4 |
# +----------------------------------------------------------------------+
# | Copyright (c) 2000 The PHP Group |
# +----------------------------------------------------------------------+
# | This source file is subject to version 2.02 of the PHP license, |
# | that is bundled with this package in the file LICENSE, and is |
# | 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. |
# +----------------------------------------------------------------------+
# | Author: Sascha Schumann <sascha@schumann.cx> |
# +----------------------------------------------------------------------+
#
# $Id$
#
# Usage:
#
# echo top_srcdir top_builddir srcdir CPP [CPP-ARGS] filenames | \
# awk -f mkdep.awk > dependencies
{
top_srcdir=$1
top_builddir=$2
srcdir=$3
cmd=$4
for (i = 5; i <= NF; i++) {
if (match($i, "^-[A-Z]") == 0)
break;
cmd=cmd " " $i
}
dif=i-1
for (; i <= NF; i++)
filenames[i-dif]=$i
no_files=NF-dif
for(i = 1; i <= no_files; i++) {
if (system("test -r " filenames[i]) != 0)
continue
target=filenames[i]
sub(srcdir "/", "", target)
target2=target
sub("\.(c|cpp)$", ".lo", target);
sub("\.(c|cpp)$", ".slo", target2);
for (e in used)
delete used[e]
cmdx=cmd " " filenames[i]
done=0
while ((cmdx | getline) > 0) {
if (match($0, "^# [0-9]* \".*\.h\"") != 0) {
if (sub(top_srcdir, "$(top_srcdir)", $3) == 0)
sub(top_builddir, "$(top_builddir)", $3)
if (substr($3,2,1) != "/" && used[$3] != 1) {
if (done == 0)
printf(target " " target2 ":")
done=1
printf(" \\\n\t" substr($3,2,length($3)-2))
used[$3] = 1;
}
}
}
if (done == 1)
print "\n"
}
}
-6
View File
@@ -1,6 +0,0 @@
/phpext_/ {
if (old_filename != FILENAME) {
printf "#include \"" FILENAME "\"@NEWLINE@"
old_filename = FILENAME
}
}
-1046
View File
File diff suppressed because it is too large. Load diff
-64
View File
@@ -1,64 +0,0 @@
#!/bin/sh
# $Id$
eval `grep '^EXTRA_VERSION=' configure.in`
case "$EXTRA_VERSION" in
*-dev)
dev=1
;;
*)
dev=0
;;
esac
devok=0
while test $# -gt 0; do
if test "$1" = "--copy"; then
automake_flags=--copy
fi
if test "$1" = "--force"; then
devok=1
echo "Forcing buildconf"
fi
shift
done
if test "$dev" = "0" -a "$devok" = "0"; then
echo "You should not run buildconf in a release package."
echo "use buildconf --force to override this check."
exit 1
fi
if test -z "$ZENDDIR"; then
if grep "PHP_MAJOR_VERSION 5" main/php_version.h >/dev/null; then
v=5
else
v=4
fi
if test "$v" = "5"; then
if test -r "Zend/OBJECTS2_HOWTO"; then
:
else
mv Zend ZendEngine1 2>/dev/null
mv ZendEngine2 Zend
fi
else
if test -r "Zend/zend_execute_globals.h"; then
:
else
mv Zend ZendEngine2 2>/dev/null
mv ZendEngine1 Zend
fi
fi
ZENDDIR=Zend
echo "using default Zend directory"
fi
rm -f generated_lists
${MAKE:-make} -s -f build/build.mk AMFLAGS="$automake_flags" ZENDDIR="$ZENDDIR"
-1363
View File
File diff suppressed because it is too large. Load diff
Vendored
-1470
View File
File diff suppressed because it is too large. Load diff
-1357
View File
File diff suppressed because it is too large. Load diff
-3
View File
@@ -1,3 +0,0 @@
#! /bin/sh
${MAKE:-make} -f build/build.mk cvsclean
-2
View File
@@ -1,2 +0,0 @@
BC Math
Andi Gutmans
-511
View File
@@ -1,511 +0,0 @@
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2003 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Andi Gutmans <andi@zend.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#if WITH_BCMATH
#include "ext/standard/info.h"
#include "php_bcmath.h"
#include "libbcmath/src/bcmath.h"
ZEND_DECLARE_MODULE_GLOBALS(bcmath);
function_entry bcmath_functions[] = {
PHP_FE(bcadd, NULL)
PHP_FE(bcsub, NULL)
PHP_FE(bcmul, NULL)
PHP_FE(bcdiv, NULL)
PHP_FE(bcmod, NULL)
PHP_FE(bcpow, NULL)
PHP_FE(bcsqrt, NULL)
PHP_FE(bcscale, NULL)
PHP_FE(bccomp, NULL)
{NULL, NULL, NULL}
};
zend_module_entry bcmath_module_entry = {
STANDARD_MODULE_HEADER,
"bcmath",
bcmath_functions,
#if ZTS
PHP_MODULE_STARTUP_N(bcmath),
#else
NULL,
#endif
NULL,
PHP_RINIT(bcmath),
PHP_RSHUTDOWN(bcmath),
PHP_MINFO(bcmath),
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_BCMATH
ZEND_GET_MODULE(bcmath)
#endif
#ifndef THREAD_SAFE
static long bc_precision;
#endif
#if ZTS
PHP_MODULE_STARTUP_D(bcmath)
{
zend_bcmath_globals *bcmath_globals;
ts_allocate_id(&bcmath_globals_id, sizeof(zend_bcmath_globals), NULL, NULL);
bcmath_globals = ts_resource(bcmath_globals_id);
return SUCCESS;
}
#endif
PHP_RSHUTDOWN_FUNCTION(bcmath)
{
bc_free_num(&BCG(_zero_));
bc_free_num(&BCG(_one_));
bc_free_num(&BCG(_two_));
return SUCCESS;
}
PHP_RINIT_FUNCTION(bcmath)
{
if (cfg_get_long("bcmath.scale", &bc_precision)==FAILURE) {
bc_precision=0;
}
if(bc_precision<0) bc_precision=0;
bc_init_numbers(TSRMLS_C);
return SUCCESS;
}
PHP_MINFO_FUNCTION(bcmath)
{
php_info_print_table_start();
php_info_print_table_row(2, "BCMath support", "enabled");
php_info_print_table_end();
}
/* {{{ php_str2num
Convert to bc_num detecting scale */
static void php_str2num(bc_num *num, char *str TSRMLS_DC)
{
char *p;
if (!(p = strchr(str, '.'))) {
bc_str2num(num, str, 0 TSRMLS_CC);
return;
}
bc_str2num(num, str, strlen(p+1) TSRMLS_CC);
}
/* }}} */
/* {{{ proto string bcadd(string left_operand, string right_operand [, int scale])
Returns the sum of two arbitrary precision numbers */
PHP_FUNCTION(bcadd)
{
pval **left, **right, **scale_param;
bc_num first, second, result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
bc_add (first, second, &result, scale);
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcsub(string left_operand, string right_operand [, int scale])
Returns the difference between two arbitrary precision numbers */
PHP_FUNCTION(bcsub)
{
pval **left, **right, **scale_param;
bc_num first, second, result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
bc_sub (first, second, &result, scale);
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcmul(string left_operand, string right_operand [, int scale])
Returns the multiplication of two arbitrary precision numbers */
PHP_FUNCTION(bcmul)
{
pval **left, **right, **scale_param;
bc_num first, second, result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
bc_multiply (first, second, &result, scale TSRMLS_CC);
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcdiv(string left_operand, string right_operand [, int scale])
Returns the quotient of two arbitrary precision numbers (division) */
PHP_FUNCTION(bcdiv)
{
pval **left, **right, **scale_param;
bc_num first, second, result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
switch (bc_divide (first, second, &result, scale TSRMLS_CC)) {
case 0: /* OK */
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
break;
case -1: /* division by zero */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero");
break;
}
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcmod(string left_operand, string right_operand)
Returns the modulus of the two arbitrary precision operands */
PHP_FUNCTION(bcmod)
{
pval **left, **right;
bc_num first, second, result;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
bc_str2num(&first, Z_STRVAL_PP(left), 0 TSRMLS_CC);
bc_str2num(&second, Z_STRVAL_PP(right), 0 TSRMLS_CC);
switch (bc_modulo(first, second, &result, 0 TSRMLS_CC)) {
case 0:
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
break;
case -1:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero");
break;
}
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcpow(string x, string y [, int scale])
Returns the value of an arbitrary precision number raised to the power of another */
PHP_FUNCTION(bcpow)
{
pval **left, **right, **scale_param;
bc_num first, second, result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
bc_raise (first, second, &result, scale TSRMLS_CC);
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto string bcsqrt(string operand [, int scale])
Returns the square root of an arbitray precision number */
PHP_FUNCTION(bcsqrt)
{
pval **left, **scale_param;
bc_num result;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &left)== FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 2:
if (zend_get_parameters_ex(2, &left, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
bc_init_num(&result TSRMLS_CC);
php_str2num(&result, Z_STRVAL_PP(left) TSRMLS_CC);
if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
if (result->n_scale > scale)
result->n_scale = scale;
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Square root of negative number");
}
bc_free_num(&result);
return;
}
/* }}} */
/* {{{ proto int bccomp(string left_operand, string right_operand [, int scale])
Compares two arbitrary precision numbers */
PHP_FUNCTION(bccomp)
{
pval **left, **right, **scale_param;
bc_num first, second;
int scale=bc_precision;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &left, &right) == FAILURE) {
WRONG_PARAM_COUNT;
}
break;
case 3:
if (zend_get_parameters_ex(3, &left, &right, &scale_param) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(scale_param);
scale = (int) (Z_LVAL_PP(scale_param)<0) ? 0:Z_LVAL_PP(scale_param);
break;
default:
WRONG_PARAM_COUNT;
break;
}
convert_to_string_ex(left);
convert_to_string_ex(right);
bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
Z_LVAL_P(return_value) = bc_compare(first, second);
Z_TYPE_P(return_value) = IS_LONG;
bc_free_num(&first);
bc_free_num(&second);
return;
}
/* }}} */
/* {{{ proto bool bcscale(int scale)
Sets default scale parameter for all bc math functions */
PHP_FUNCTION(bcscale)
{
pval **new_scale;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &new_scale)==FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(new_scale);
bc_precision = (Z_LVAL_PP(new_scale)<0) ? 0 : Z_LVAL_PP(new_scale);
RETURN_TRUE;
}
/* }}} */
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/
-17
View File
@@ -1,17 +0,0 @@
dnl
dnl $Id$
dnl
PHP_ARG_ENABLE(bcmath, whether to enable bc style precision math functions,
[ --enable-bcmath Enable bc style precision math functions.])
if test "$PHP_BCMATH" != "no"; then
AC_DEFINE(WITH_BCMATH, 1, [Whether you have bcmath])
PHP_NEW_EXTENSION(bcmath, bcmath.c number.c \
libbcmath/src/add.c libbcmath/src/div.c libbcmath/src/init.c libbcmath/src/neg.c libbcmath/src/outofmem.c libbcmath/src/raisemod.c libbcmath/src/rt.c libbcmath/src/sub.c \
libbcmath/src/compare.c libbcmath/src/divmod.c libbcmath/src/int2num.c libbcmath/src/num2long.c libbcmath/src/output.c libbcmath/src/recmul.c \
libbcmath/src/sqrt.c libbcmath/src/zero.c libbcmath/src/debug.c libbcmath/src/doaddsub.c libbcmath/src/nearzero.c libbcmath/src/num2str.c libbcmath/src/raise.c \
libbcmath/src/rmzero.c libbcmath/src/str2num.c,
$ext_shared,,-I@ext_srcdir@/libbcmath/src)
PHP_ADD_BUILD_DIR($ext_builddir/libbcmath/src)
fi
-3
View File
@@ -1,3 +0,0 @@
Phil Nelson <philnelson@acm.org> wrote bcmath library.
-515
View File
@@ -1,515 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
^L
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
^L
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
^L
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
^L
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
^L
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
^L
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
^L
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
^L
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
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 library's name and a brief idea of what it
does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper
mail.
You should also get your employer (if you work as a programmer) or
your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
-10
View File
@@ -1,10 +0,0 @@
Wed Jun 7 09:39:02 2000 Phil Nelson <phil@cs.wwu.edu>
* configure.in and many others: version number now at 0.2.
Many other changes/additions for getting a distribution
to work.
2000-05-21 Phil Nelson <phil@cs.wwu.edu>
* Initial setup of bcmath library., calling it version 0.1.
-21
View File
@@ -1,21 +0,0 @@
BCMATH FAQ:
1) Why BCMATH?
The math routines of GNU bc become more generally useful in a
library form. By separating the BCMATH library from GNU bc,
GNU bc can be under the GPL and BCMATH can be under the LGPL.
2) Why BCMATH when GMP exists?
GMP has "integers" (no digits after a decimal), "rational numbers"
(stored as 2 integers) and "floats". None of these will correctly
represent a POSIX BC number. Floats are the closest, but will not
behave correctly for many computations. For example, BC numbers have
a "scale" that represent the number of digits to represent after the
decimal point. The multiplying two of these numbers requires one to
calculate an exact number of digits after the decimal point regardless
of the number of digits in the integer part. GMP floats have a
"fixed, but arbitrary" mantissa and so multiplying two floats will end
up dropping digits BC must calculate.
-9
View File
@@ -1,9 +0,0 @@
Currently, only libbcmath.a is built. To build and install it, do
configure
make
make install
Typical configure parameters are available. (e.g. PREFIX)
Bugs and comments to philnelson@acm.org.
-12
View File
@@ -1,12 +0,0 @@
## Process this file with automake to produce Makefile.in
SUBDIRS= src doc
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
stamp-h.in *~
dist-hook:
cp $(srcdir)/doc/bcmath.1 $(distdir)/doc
cp $(srcdir)/src/private.h $(distdir)/src
cp $(srcdir)/FAQ $(distdir)
-3
View File
@@ -1,3 +0,0 @@
NEWS for bcmath library:
May 2000: The library is created.
-9
View File
@@ -1,9 +0,0 @@
This is bcmath, a library of arbitrary precision math routines.
These routines, in a different form, are the routines that to
the arbitrary precision calculations for GNU bc and GNU dc.
This library is provided to make these routines useful in a
larger context with less restrictions on the use of them.
These routines do not duplicate functionality of the GNU gmp
library. gmp is similar, but the actual computation is different.
-9
View File
@@ -1,9 +0,0 @@
/* PACKAGE name */
#undef PACKAGE
/* Package VERSION number */
#undef VERSION
/* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */
#undef ptrdiff_t
-127
View File
@@ -1,127 +0,0 @@
dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
# serial 1
dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
AC_DEFUN(AM_INIT_AUTOMAKE,
[AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
AC_SUBST(VERSION)
dnl test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
ifelse([$3],,
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
#
# 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
if test "[$]*" != "X $srcdir/configure conftestfile" \
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
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)])
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
dnl The program must properly implement --version.
AC_DEFUN(AM_MISSING_PROG,
[AC_MSG_CHECKING(for working $2)
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if ($2 --version) < /dev/null > /dev/null 2>&1; then
$1=$2
AC_MSG_RESULT(found)
else
$1="$3/missing $2"
AC_MSG_RESULT(missing)
fi
AC_SUBST($1)])
# Like AC_CONFIG_HEADER, but automatically create stamp file.
AC_DEFUN(AM_CONFIG_HEADER,
[AC_PREREQ([2.12])
AC_CONFIG_HEADER([$1])
dnl When config.status generates a header, we must update the stamp-h file.
dnl This file resides in the same directory as the config header
dnl that is generated. We must strip everything past the first ":",
dnl and everything past the last "/".
AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
<<am_indx=1
for am_file in <<$1>>; do
case " <<$>>CONFIG_HEADERS " in
*" <<$>>am_file "*<<)>>
echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
;;
esac
am_indx=`expr "<<$>>am_indx" + 1`
done<<>>dnl>>)
changequote([,]))])
-41
View File
@@ -1,41 +0,0 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */
#undef ptrdiff_t
/* Define if you have the <lib.h> header file. */
#undef HAVE_LIB_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Version number of package */
#undef VERSION
-1859
View File
File diff suppressed because it is too large. Load diff
-18
View File
@@ -1,18 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(doc/bcmath.1)
AM_INIT_AUTOMAKE("bcmath", "0.2")
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_PROG_MAKE_SET
AC_CHECK_HEADERS(stdarg.h stddef.h stdlib.h string.h limits.h unistd.h lib.h)
AC_C_CONST
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ptrdiff_t, size_t)
AC_OUTPUT(Makefile src/Makefile doc/Makefile)
-238
View File
@@ -1,238 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
tranformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
-134
View File
@@ -1,134 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison touch file \`y.tab.c'
makeinfo touch the output file
yacc touch file \`y.tab.c'"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
touch config.h.in
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print \
| sed 's/^\(.*\).am$/touch \1.in/' \
| sh
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
your modified any \`.y' file. For being effective, your
modifications might require the \`Bison' package. Grab it from
any GNU archive site."
touch y.tab.c
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. It should be needed only if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
-36
View File
@@ -1,36 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
errstatus=0
for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
fi
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
-22
View File
@@ -1,22 +0,0 @@
# Makefile for bcmath library
lib_LIBRARIES = libbcmath.a
include_HEADERS = bcmath.h
libbcmath_a_SOURCES= add.c compare.c debug.c div.c divmod.c doaddsub.c \
init.c int2num.c nearzero.c neg.c num2long.c num2str.c output.c \
raise.c raisemod.c recmul.c rmzero.c sqrt.c str2num.c sub.c zero.c \
outofmem.c rt.c
INCLUDES = -I$(srcdir) -I..
CFLAGS = @CFLAGS@
CPPFLAGS = $(INCLUDES) -Wall
MAINTAINERCLEANFILES= Makefile.in $(libbcmath_a_SOURCES) private.h bcmath.h
all: $(bin_LIBRARIES)
clean:
rm -f $(OBJS) $(LIB) *~
-88
View File
@@ -1,88 +0,0 @@
/* add.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Here is the full add routine that takes care of negative numbers.
N1 is added to N2 and the result placed into RESULT. SCALE_MIN
is the minimum scale for the result. */
void
bc_add (n1, n2, result, scale_min)
bc_num n1, n2, *result;
int scale_min;
{
bc_num sum = NULL;
int cmp_res;
int res_scale;
if (n1->n_sign == n2->n_sign)
{
sum = _bc_do_add (n1, n2, scale_min);
sum->n_sign = n1->n_sign;
}
else
{
/* subtraction must be done. */
cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */
switch (cmp_res)
{
case -1:
/* n1 is less than n2, subtract n1 from n2. */
sum = _bc_do_sub (n2, n1, scale_min);
sum->n_sign = n2->n_sign;
break;
case 0:
/* They are equal! return zero with the correct scale! */
res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale));
sum = bc_new_num (1, res_scale);
memset (sum->n_value, 0, res_scale+1);
break;
case 1:
/* n2 is less than n1, subtract n2 from n1. */
sum = _bc_do_sub (n1, n2, scale_min);
sum->n_sign = n1->n_sign;
}
}
/* Clean up and return. */
bc_free_num (result);
*result = sum;
}
-155
View File
@@ -1,155 +0,0 @@
/* bcmath.h: bcmath library header. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#ifndef _BCMATH_H_
#define _BCMATH_H_
typedef enum {PLUS, MINUS} sign;
typedef struct bc_struct *bc_num;
typedef struct bc_struct
{
sign n_sign;
int n_len; /* The number of digits before the decimal point. */
int n_scale; /* The number of digits after the decimal point. */
int n_refs; /* The number of pointers to this number. */
bc_num n_next; /* Linked list for available list. */
char *n_ptr; /* The pointer to the actual storage.
If NULL, n_value points to the inside of
another number (bc_multiply...) and should
not be "freed." */
char *n_value; /* The number. Not zero char terminated.
May not point to the same place as n_ptr as
in the case of leading zeros generated. */
} bc_struct;
#include <php.h>
#include <ext/bcmath/php_bcmath.h>
/* The base used in storing the numbers in n_value above.
Currently this MUST be 10. */
#define BASE 10
/* Some useful macros and constants. */
#define CH_VAL(c) (c - '0')
#define BCD_CHAR(d) (d + '0')
#ifdef MIN
#undef MIN
#undef MAX
#endif
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)>(b)?(b):(a))
#define ODD(a) ((a)&1)
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef LONG_MAX
#define LONG_MAX 0x7ffffff
#endif
/* Function Prototypes */
/* Define the _PROTOTYPE macro if it is needed. */
#ifndef _PROTOTYPE
#ifdef __STDC__
#define _PROTOTYPE(func, args) func args
#else
#define _PROTOTYPE(func, args) func()
#endif
#endif
_PROTOTYPE(void bc_init_numbers, (TSRMLS_D));
_PROTOTYPE(bc_num bc_new_num, (int length, int scale));
_PROTOTYPE(void bc_free_num, (bc_num *num));
_PROTOTYPE(bc_num bc_copy_num, (bc_num num));
_PROTOTYPE(void bc_init_num, (bc_num *num TSRMLS_DC));
_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale TSRMLS_DC));
_PROTOTYPE(char *bc_num2str, (bc_num num));
_PROTOTYPE(void bc_int2num, (bc_num *num, int val));
_PROTOTYPE(long bc_num2long, (bc_num num));
_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2));
_PROTOTYPE(char bc_is_zero, (bc_num num TSRMLS_DC));
_PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale));
_PROTOTYPE(char bc_is_neg, (bc_num num));
_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale TSRMLS_DC));
_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale TSRMLS_DC));
_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result,
int scale TSRMLS_DC));
_PROTOTYPE(int bc_divmod, (bc_num num1, bc_num num2, bc_num *quot,
bc_num *rem, int scale TSRMLS_DC));
_PROTOTYPE(int bc_raisemod, (bc_num base, bc_num expo, bc_num mod,
bc_num *result, int scale TSRMLS_DC));
_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result,
int scale TSRMLS_DC));
_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale TSRMLS_DC));
_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int),
int leading_zero TSRMLS_DC));
/* Prototypes needed for external utility routines. */
_PROTOTYPE(void bc_rt_warn, (char *mesg ,...));
_PROTOTYPE(void bc_rt_error, (char *mesg ,...));
_PROTOTYPE(void bc_out_of_memory, (void));
#endif
-161
View File
@@ -1,161 +0,0 @@
/* compare.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less
than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
compare the magnitudes. */
int
_bc_do_compare (n1, n2, use_sign, ignore_last)
bc_num n1, n2;
int use_sign;
int ignore_last;
{
char *n1ptr, *n2ptr;
int count;
/* First, compare signs. */
if (use_sign && n1->n_sign != n2->n_sign)
{
if (n1->n_sign == PLUS)
return (1); /* Positive N1 > Negative N2 */
else
return (-1); /* Negative N1 < Positive N1 */
}
/* Now compare the magnitude. */
if (n1->n_len != n2->n_len)
{
if (n1->n_len > n2->n_len)
{
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS)
return (1);
else
return (-1);
}
else
{
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS)
return (-1);
else
return (1);
}
}
/* If we get here, they have the same number of integer digits.
check the integer part and the equal length part of the fraction. */
count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
n1ptr = n1->n_value;
n2ptr = n2->n_value;
while ((count > 0) && (*n1ptr == *n2ptr))
{
n1ptr++;
n2ptr++;
count--;
}
if (ignore_last && count == 1 && n1->n_scale == n2->n_scale)
return (0);
if (count != 0)
{
if (*n1ptr > *n2ptr)
{
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS)
return (1);
else
return (-1);
}
else
{
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS)
return (-1);
else
return (1);
}
}
/* They are equal up to the last part of the equal part of the fraction. */
if (n1->n_scale != n2->n_scale)
{
if (n1->n_scale > n2->n_scale)
{
for (count = n1->n_scale-n2->n_scale; count>0; count--)
if (*n1ptr++ != 0)
{
/* Magnitude of n1 > n2. */
if (!use_sign || n1->n_sign == PLUS)
return (1);
else
return (-1);
}
}
else
{
for (count = n2->n_scale-n1->n_scale; count>0; count--)
if (*n2ptr++ != 0)
{
/* Magnitude of n1 < n2. */
if (!use_sign || n1->n_sign == PLUS)
return (-1);
else
return (1);
}
}
}
/* They must be equal! */
return (0);
}
/* This is the "user callable" routine to compare numbers N1 and N2. */
int
bc_compare (n1, n2)
bc_num n1, n2;
{
return _bc_do_compare (n1, n2, TRUE, FALSE);
}
-11
View File
@@ -1,11 +0,0 @@
#if PHP_WIN32
#include "../../../../main/config.w32.h"
#elif defined(NETWARE)
#include "config.nw.h"
#else
#include "php_config.h"
#endif
#include <string.h>
#include "zend.h"
#include "zend_alloc.h"
-69
View File
@@ -1,69 +0,0 @@
/* debug.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* pn prints the number NUM in base 10. */
static void
out_char (int c)
{
putchar(c);
}
void
pn (bc_num num TSRMLS_DC)
{
bc_out_num (num, 10, out_char, 0 TSRMLS_CC);
out_char ('\n');
}
/* pv prints a character array as if it was a string of bcd digits. */
void
pv (name, num, len)
char *name;
unsigned char *num;
int len;
{
int i;
printf ("%s=", name);
for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i]));
printf ("\n");
}
-274
View File
@@ -1,274 +0,0 @@
/* div.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Some utility routines for the divide: First a one digit multiply.
NUM (with SIZE digits) is multiplied by DIGIT and the result is
placed into RESULT. It is written so that NUM and RESULT can be
the same pointers. */
static void
_one_mult (num, size, digit, result)
unsigned char *num;
int size, digit;
unsigned char *result;
{
int carry, value;
unsigned char *nptr, *rptr;
if (digit == 0)
memset (result, 0, size);
else
{
if (digit == 1)
memcpy (result, num, size);
else
{
/* Initialize */
nptr = (unsigned char *) (num+size-1);
rptr = (unsigned char *) (result+size-1);
carry = 0;
while (size-- > 0)
{
value = *nptr-- * digit + carry;
*rptr-- = value % BASE;
carry = value / BASE;
}
if (carry != 0) *rptr = carry;
}
}
}
/* The full division routine. This computes N1 / N2. It returns
0 if the division is ok and the result is in QUOT. The number of
digits after the decimal point is SCALE. It returns -1 if division
by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
int
bc_divide (bc_num n1, bc_num n2, bc_num *quot, int scale TSRMLS_DC)
{
bc_num qval;
unsigned char *num1, *num2;
unsigned char *ptr1, *ptr2, *n2ptr, *qptr;
int scale1, val;
unsigned int len1, len2, scale2, qdigits, extra, count;
unsigned int qdig, qguess, borrow, carry;
unsigned char *mval;
char zero;
unsigned int norm;
/* Test for divide by zero. */
if (bc_is_zero (n2 TSRMLS_CC)) return -1;
/* Test for divide by 1. If it is we must truncate. */
if (n2->n_scale == 0)
{
if (n2->n_len == 1 && *n2->n_value == 1)
{
qval = bc_new_num (n1->n_len, scale);
qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
memset (&qval->n_value[n1->n_len],0,scale);
memcpy (qval->n_value, n1->n_value,
n1->n_len + MIN(n1->n_scale,scale));
bc_free_num (quot);
*quot = qval;
}
}
/* Set up the divide. Move the decimal point on n1 by n2's scale.
Remember, zeros on the end of num2 are wasted effort for dividing. */
scale2 = n2->n_scale;
n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1;
while ((scale2 > 0) && (*n2ptr-- == 0)) scale2--;
len1 = n1->n_len + scale2;
scale1 = n1->n_scale - scale2;
if (scale1 < scale)
extra = scale - scale1;
else
extra = 0;
num1 = (unsigned char *) emalloc (n1->n_len+n1->n_scale+extra+2);
if (num1 == NULL) bc_out_of_memory();
memset (num1, 0, n1->n_len+n1->n_scale+extra+2);
memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale);
len2 = n2->n_len + scale2;
num2 = (unsigned char *) emalloc (len2+1);
if (num2 == NULL) bc_out_of_memory();
memcpy (num2, n2->n_value, len2);
*(num2+len2) = 0;
n2ptr = num2;
while (*n2ptr == 0)
{
n2ptr++;
len2--;
}
/* Calculate the number of quotient digits. */
if (len2 > len1+scale)
{
qdigits = scale+1;
zero = TRUE;
}
else
{
zero = FALSE;
if (len2>len1)
qdigits = scale+1; /* One for the zero integer part. */
else
qdigits = len1-len2+scale+1;
}
/* Allocate and zero the storage for the quotient. */
qval = bc_new_num (qdigits-scale,scale);
memset (qval->n_value, 0, qdigits);
/* Allocate storage for the temporary storage mval. */
mval = (unsigned char *) emalloc (len2+1);
if (mval == NULL) bc_out_of_memory ();
/* Now for the full divide algorithm. */
if (!zero)
{
/* Normalize */
norm = 10 / ((int)*n2ptr + 1);
if (norm != 1)
{
_one_mult (num1, len1+scale1+extra+1, norm, num1);
_one_mult (n2ptr, len2, norm, n2ptr);
}
/* Initialize divide loop. */
qdig = 0;
if (len2 > len1)
qptr = (unsigned char *) qval->n_value+len2-len1;
else
qptr = (unsigned char *) qval->n_value;
/* Loop */
while (qdig <= len1+scale-len2)
{
/* Calculate the quotient digit guess. */
if (*n2ptr == num1[qdig])
qguess = 9;
else
qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr;
/* Test qguess. */
if (n2ptr[1]*qguess >
(num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
+ num1[qdig+2])
{
qguess--;
/* And again. */
if (n2ptr[1]*qguess >
(num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
+ num1[qdig+2])
qguess--;
}
/* Multiply and subtract. */
borrow = 0;
if (qguess != 0)
{
*mval = 0;
_one_mult (n2ptr, len2, qguess, mval+1);
ptr1 = (unsigned char *) num1+qdig+len2;
ptr2 = (unsigned char *) mval+len2;
for (count = 0; count < len2+1; count++)
{
val = (int) *ptr1 - (int) *ptr2-- - borrow;
if (val < 0)
{
val += 10;
borrow = 1;
}
else
borrow = 0;
*ptr1-- = val;
}
}
/* Test for negative result. */
if (borrow == 1)
{
qguess--;
ptr1 = (unsigned char *) num1+qdig+len2;
ptr2 = (unsigned char *) n2ptr+len2-1;
carry = 0;
for (count = 0; count < len2; count++)
{
val = (int) *ptr1 + (int) *ptr2-- + carry;
if (val > 9)
{
val -= 10;
carry = 1;
}
else
carry = 0;
*ptr1-- = val;
}
if (carry == 1) *ptr1 = (*ptr1 + 1) % 10;
}
/* We now know the quotient digit. */
*qptr++ = qguess;
qdig++;
}
}
/* Clean up and return the number. */
qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
if (bc_is_zero (qval TSRMLS_CC)) qval->n_sign = PLUS;
_bc_rm_leading_zeros (qval);
bc_free_num (quot);
*quot = qval;
/* Clean up temporary storage. */
efree (mval);
efree (num1);
efree (num2);
return 0; /* Everything is OK. */
}
-87
View File
@@ -1,87 +0,0 @@
/* divmod.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Division *and* modulo for numbers. This computes both NUM1 / NUM2 and
NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT
is NULL then that store will be omitted.
*/
int
bc_divmod (bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, int scale TSRMLS_DC)
{
bc_num quotient = NULL;
bc_num temp;
int rscale;
/* Check for correct numbers. */
if (bc_is_zero (num2 TSRMLS_CC)) return -1;
/* Calculate final scale. */
rscale = MAX (num1->n_scale, num2->n_scale+scale);
bc_init_num(&temp TSRMLS_CC);
/* Calculate it. */
bc_divide (num1, num2, &temp, scale TSRMLS_CC);
if (quot)
quotient = bc_copy_num (temp);
bc_multiply (temp, num2, &temp, rscale TSRMLS_CC);
bc_sub (num1, temp, rem, rscale);
bc_free_num (&temp);
if (quot)
{
bc_free_num (quot);
*quot = quotient;
}
return 0; /* Everything is OK. */
}
/* Modulo for numbers. This computes NUM1 % NUM2 and puts the
result in RESULT. */
int
bc_modulo (bc_num num1, bc_num num2, bc_num *result, int scale TSRMLS_DC)
{
return bc_divmod (num1, num2, NULL, result, scale TSRMLS_CC);
}
-232
View File
@@ -1,232 +0,0 @@
/* doaddsub.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Perform addition: N1 is added to N2 and the value is
returned. The signs of N1 and N2 are ignored.
SCALE_MIN is to set the minimum scale of the result. */
bc_num
_bc_do_add (n1, n2, scale_min)
bc_num n1, n2;
int scale_min;
{
bc_num sum;
int sum_scale, sum_digits;
char *n1ptr, *n2ptr, *sumptr;
int carry, n1bytes, n2bytes;
int count;
/* Prepare sum. */
sum_scale = MAX (n1->n_scale, n2->n_scale);
sum_digits = MAX (n1->n_len, n2->n_len) + 1;
sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min));
/* Zero extra digits made by scale_min. */
if (scale_min > sum_scale)
{
sumptr = (char *) (sum->n_value + sum_scale + sum_digits);
for (count = scale_min - sum_scale; count > 0; count--)
*sumptr++ = 0;
}
/* Start with the fraction part. Initialize the pointers. */
n1bytes = n1->n_scale;
n2bytes = n2->n_scale;
n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1);
n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1);
sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1);
/* Add the fraction part. First copy the longer fraction.*/
if (n1bytes != n2bytes)
{
if (n1bytes > n2bytes)
while (n1bytes>n2bytes)
{ *sumptr-- = *n1ptr--; n1bytes--;}
else
while (n2bytes>n1bytes)
{ *sumptr-- = *n2ptr--; n2bytes--;}
}
/* Now add the remaining fraction part and equal size integer parts. */
n1bytes += n1->n_len;
n2bytes += n2->n_len;
carry = 0;
while ((n1bytes > 0) && (n2bytes > 0))
{
*sumptr = *n1ptr-- + *n2ptr-- + carry;
if (*sumptr > (BASE-1))
{
carry = 1;
*sumptr -= BASE;
}
else
carry = 0;
sumptr--;
n1bytes--;
n2bytes--;
}
/* Now add carry the longer integer part. */
if (n1bytes == 0)
{ n1bytes = n2bytes; n1ptr = n2ptr; }
while (n1bytes-- > 0)
{
*sumptr = *n1ptr-- + carry;
if (*sumptr > (BASE-1))
{
carry = 1;
*sumptr -= BASE;
}
else
carry = 0;
sumptr--;
}
/* Set final carry. */
if (carry == 1)
*sumptr += 1;
/* Adjust sum and return. */
_bc_rm_leading_zeros (sum);
return sum;
}
/* Perform subtraction: N2 is subtracted from N1 and the value is
returned. The signs of N1 and N2 are ignored. Also, N1 is
assumed to be larger than N2. SCALE_MIN is the minimum scale
of the result. */
bc_num
_bc_do_sub (n1, n2, scale_min)
bc_num n1, n2;
int scale_min;
{
bc_num diff;
int diff_scale, diff_len;
int min_scale, min_len;
char *n1ptr, *n2ptr, *diffptr;
int borrow, count, val;
/* Allocate temporary storage. */
diff_len = MAX (n1->n_len, n2->n_len);
diff_scale = MAX (n1->n_scale, n2->n_scale);
min_len = MIN (n1->n_len, n2->n_len);
min_scale = MIN (n1->n_scale, n2->n_scale);
diff = bc_new_num (diff_len, MAX(diff_scale, scale_min));
/* Zero extra digits made by scale_min. */
if (scale_min > diff_scale)
{
diffptr = (char *) (diff->n_value + diff_len + diff_scale);
for (count = scale_min - diff_scale; count > 0; count--)
*diffptr++ = 0;
}
/* Initialize the subtract. */
n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1);
n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1);
diffptr = (char *) (diff->n_value + diff_len + diff_scale -1);
/* Subtract the numbers. */
borrow = 0;
/* Take care of the longer scaled number. */
if (n1->n_scale != min_scale)
{
/* n1 has the longer scale */
for (count = n1->n_scale - min_scale; count > 0; count--)
*diffptr-- = *n1ptr--;
}
else
{
/* n2 has the longer scale */
for (count = n2->n_scale - min_scale; count > 0; count--)
{
val = - *n2ptr-- - borrow;
if (val < 0)
{
val += BASE;
borrow = 1;
}
else
borrow = 0;
*diffptr-- = val;
}
}
/* Now do the equal length scale and integer parts. */
for (count = 0; count < min_len + min_scale; count++)
{
val = *n1ptr-- - *n2ptr-- - borrow;
if (val < 0)
{
val += BASE;
borrow = 1;
}
else
borrow = 0;
*diffptr-- = val;
}
/* If n1 has more digits then n2, we now do that subtract. */
if (diff_len != min_len)
{
for (count = diff_len - min_len; count > 0; count--)
{
val = *n1ptr-- - borrow;
if (val < 0)
{
val += BASE;
borrow = 1;
}
else
borrow = 0;
*diffptr-- = val;
}
}
/* Clean up and return. */
_bc_rm_leading_zeros (diff);
return diff;
}
-130
View File
@@ -1,130 +0,0 @@
/* init.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
#ifdef SANDER_0
bc_num _bc_Free_list = NULL;
#endif
/* new_num allocates a number and sets fields to known values. */
bc_num
bc_new_num (length, scale)
int length, scale;
{
bc_num temp;
/* PHP Change: malloc() -> emalloc(), removed free_list code */
temp = (bc_num) emalloc (sizeof(bc_struct)+length+scale);
#if 0
if (_bc_Free_list != NULL) {
temp = _bc_Free_list;
_bc_Free_list = temp->n_next;
} else {
temp = (bc_num) emalloc (sizeof(bc_struct));
if (temp == NULL) bc_out_of_memory ();
}
#endif
temp->n_sign = PLUS;
temp->n_len = length;
temp->n_scale = scale;
temp->n_refs = 1;
/* PHP Change: malloc() -> emalloc() */
temp->n_ptr = (char *) emalloc (length+scale);
if (temp->n_ptr == NULL) bc_out_of_memory();
temp->n_value = temp->n_ptr;
memset (temp->n_ptr, 0, length+scale);
return temp;
}
/* "Frees" a bc_num NUM. Actually decreases reference count and only
frees the storage if reference count is zero. */
void
bc_free_num (num)
bc_num *num;
{
if (*num == NULL) return;
(*num)->n_refs--;
if ((*num)->n_refs == 0) {
if ((*num)->n_ptr)
/* PHP Change: free() -> efree(), removed free_list code */
efree ((*num)->n_ptr);
efree(*num);
#if 0
(*num)->n_next = _bc_Free_list;
_bc_Free_list = *num;
#endif
}
*num = NULL;
}
/* Intitialize the number package! */
void
bc_init_numbers (TSRMLS_D)
{
BCG(_zero_) = bc_new_num (1,0);
BCG(_one_) = bc_new_num (1,0);
BCG(_one_)->n_value[0] = 1;
BCG(_two_) = bc_new_num (1,0);
BCG(_two_)->n_value[0] = 2;
}
/* Make a copy of a number! Just increments the reference count! */
bc_num
bc_copy_num (bc_num num)
{
num->n_refs++;
return num;
}
/* Initialize a number NUM by making it a copy of zero. */
void
bc_init_num (bc_num *num TSRMLS_DC)
{
*num = bc_copy_num (BCG(_zero_));
}
-84
View File
@@ -1,84 +0,0 @@
/* int2num.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Convert an integer VAL to a bc number NUM. */
void
bc_int2num (num, val)
bc_num *num;
int val;
{
char buffer[30];
char *bptr, *vptr;
int ix = 1;
char neg = 0;
/* Sign. */
if (val < 0)
{
neg = 1;
val = -val;
}
/* Get things going. */
bptr = buffer;
*bptr++ = val % BASE;
val = val / BASE;
/* Extract remaining digits. */
while (val != 0)
{
*bptr++ = val % BASE;
val = val / BASE;
ix++; /* Count the digits. */
}
/* Make the number. */
bc_free_num (num);
*num = bc_new_num (ix, 0);
if (neg) (*num)->n_sign = MINUS;
/* Assign the digits. */
vptr = (*num)->n_value;
while (ix-- > 0)
*vptr++ = *--bptr;
}
-69
View File
@@ -1,69 +0,0 @@
/* nearzero.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* In some places we need to check if the number NUM is almost zero.
Specifically, all but the last digit is 0 and the last digit is 1.
Last digit is defined by scale. */
char
bc_is_near_zero (num, scale)
bc_num num;
int scale;
{
int count;
char *nptr;
/* Error checking */
if (scale > num->n_scale)
scale = num->n_scale;
/* Initialize */
count = num->n_len + scale;
nptr = num->n_value;
/* The check */
while ((count > 0) && (*nptr++ == 0)) count--;
if (count != 0 && (count != 1 || *--nptr != 1))
return FALSE;
else
return TRUE;
}
-49
View File
@@ -1,49 +0,0 @@
/* neg.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* In some places we need to check if the number is negative. */
char
bc_is_neg (num)
bc_num num;
{
return num->n_sign == MINUS;
}
-70
View File
@@ -1,70 +0,0 @@
/* num2long.c: bcmath library file. */
/*
Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
Copyright (C) 2000 Philip A. Nelson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details. (COPYING.LIB)
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA.
You may contact the author by:
e-mail: philnelson@acm.org
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include "bcmath.h"
#include "private.h"
/* Convert a number NUM to a long. The function returns only the integer
part of the number. For numbers that are too large to represent as
a long, this function returns a zero. This can be detected by checking
the NUM for zero after having a zero returned. */
long
bc_num2long (num)
bc_num num;
{
long val;
char *nptr;
int index;
/* Extract the int value, ignore the fraction. */
val = 0;
nptr = num->n_value;
for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--)
val = val*BASE + *nptr++;
/* Check for overflow. If overflow, return zero. */
if (index>0) val = 0;
if (val < 0) val = 0;
/* Return the value. */
if (num->n_sign == PLUS)
return (val);
else
return (-val);
}
Loaded 100 of 2163 files, more files were not shown because too many files have changed in this diff. Show more